BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #42617同步于 2010/8/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

请教大家,关于代码执行效率的问题

SunShow
2010/8/23镜像同步8 回复
vector<complex<double>> // 定义复数型vector作为矩阵容器 // 函数1,执行double型乘以复数矩阵 vector <complex<double>> CMatrixMulDouble(double dA, vector<complex<double>> &vB) { vector<complex<double>> vC; complex<double> cdTemp; for(vector<complex<double>>::size_type i=0; i<vB.size(); i++) { cdTemp = dA*vB[i]; vC.push_back(cdTemp); } return vC; } // 函数2,执行两矩阵相乘(只取对角线元素) vector <complex<double>> CMatrixDiagMul(vector<complex<double>> &vCA, vector<complex<double>> &vCB, int m, int n, int k) { // 参数检查 if (m != k) { cout<<"m不等于k,矩阵计算结果不是方阵,不能取对角线元素"<<endl; } vector<complex<double>> vCC; vCC.assign(m*m,complex<double>(0,0)); // 定义全零元素的复数方阵 for (int N=0; N<m; N++) { complex<double> ctemp; for (int M=0; M<n; M++) { ctemp += vCA[M*m+N] * vCB[M+N*n]; } vCC.at(N*m+N) = ctemp; // 对角线元素赋值 } return vCC; } // 主函数如下: void main() { vector<complex<double>> vca,vcb; complex<double> cinitial(2,3); complex<double> cinitial2(1,1); vcb.assign(12,complex<double>()); for (int nNum=0; nNum<12; nNum++) // 初始化两个vector { vca.push_back(cinitial); vcb.at(nNum) = (cinitial); cinitial += cinitial2; } // 执行1000次,分别看其时间 long LTime1 = GetTickCount(); for (int n =0; n<1000; n++) { CMatrixMulDouble(0.06592314, vca); } long LTime2 = GetTickCount(); cout<< LTime2-LTime1<<endl; for (int n=0; n<1000; n++) { CMatrixDiagMul(vca, vcb, 4, 3, 4); } long LTime2 = GetTickCount(); cout<< LTime2-LTime1<<endl; retutn; } 问题描述: 函数1循环体内部执行12次 复数乘以double型操作 函数2循环体内部执行16次循环,执行复数乘以复数操作 理论上第二个函数比第一个函数慢,可是结果是函数2的执行时间只有函数1的一半都不到。这是为什么?请大家指教。因为工程中要调用大量的函数,所以不得不挨个函数优化...麻烦大家了。
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
guo机器人#1 · 2010/8/23
在main中調用100000次function 可以看到 func1的hot-spot是14、15行的1200000次乘法與push_back func2的hot-spot是35行的1200000次乘法 push_back是很耗時間的~~~ ---------------------------------------------- -: 0:Source:a.cpp -: 0:Graph:a.gcno -: 0:Data:a.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <vector> -: 2:#include <complex> -: 3:#include <iostream> -: 4: -: 5:using namespace std; -: 6://vector<complex<double>> // 定义复数型vector作为矩阵容器 -: 7:// 函数1,执行double型乘以复数矩阵 100000: 8:vector <complex<double> > CMatrixMulDouble(double dA, vector<complex<double> > &vB) -: 9:{ 100000: 10: vector<complex<double> > vC; 100000: 11: complex<double> cdTemp; 1300000: 12: for(vector<complex<double> >::size_type i=0; i<vB.size(); i++) -: 13: { 1200000: 14: cdTemp = dA*vB[i]; 1200000: 15: vC.push_back(cdTemp); -: 16: } #####: 17: return vC; -: 18:} -: 19:// 函数2,执行两矩阵相乘(只取对角线元素) 100000: 20:vector <complex<double> > CMatrixDiagMul(vector<complex<double> > &vCA, vector<complex<double> > &vCB, int m, int n, int k) -: 21:{ -: 22: // 参数检查 100000: 23: if (m != k) -: 24: { #####: 25: cout<<"m不等于k,矩阵计算结果不是方阵,不能取对角线元素"<<endl; -: 26: } -: 27: 100000: 28: vector<complex<double> > vCC; 100000: 29: vCC.assign(m*m,complex<double>(0,0)); // 定义全零元素的复数方阵 500000: 30: for (int N=0; N<m; N++) -: 31: { 400000: 32: complex<double> ctemp; 1600000: 33: for (int M=0; M<n; M++) -: 34: { 1200000: 35: ctemp += vCA[M*m+N] * vCB[M+N*n]; -: 36: } 400000: 37: vCC.at(N*m+N) = ctemp; // 对角线元素赋值 -: 38: } #####: 39: return vCC; -: 40:} -: 41: -: 42:// 主函数如下: 1: 43:int main() -: 44:{ 1: 45: vector<complex<double> > vca,vcb; 1: 46: complex<double> cinitial(2,3); 1: 47: complex<double> cinitial2(1,1); 1: 48: vcb.assign(12,complex<double>()); 13: 49: for (int nNum=0; nNum<12; nNum++) // 初始化两个vector -: 50: { 12: 51: vca.push_back(cinitial); 12: 52: vcb.at(nNum) = (cinitial); 12: 53: cinitial += cinitial2; -: 54: } -: 55: // 执行1000次,分别看其时间 -: 56:// long LTime1 = GetTickCount(); 100001: 57: for (int n =0; n<100000; n++) -: 58: { 100000: 59: CMatrixMulDouble(0.06592314, vca); -: 60: } -: 61:// long LTime2 = GetTickCount(); -: 62:// cout<< LTime2-LTime1<<endl; -: 63: 100001: 64: for (int n=0; n<100000; n++) -: 65: { 100000: 66: CMatrixDiagMul(vca, vcb, 4, 3, 4); -: 67: } -: 68:// long LTime2 = GetTickCount(); -: 69:// cout<< LTime2-LTime1<<endl; -: 70: 1: 71: return 0; 2: 72:} 1: 73:/*EOF*/
ericyosho机器人#2 · 2010/8/23
前面那个函数,没循环一次,都要进行函数的调用。 vB.size()还有push_back 后面那个函数,没有函数调用,一开始都把空间分配好了。
guo机器人#3 · 2010/8/23
granularity: each sample hit covers 2 byte(s) for 1.04% of 0.96 seconds index % time self children called name <spontaneous> [1] 100.0 0.02 0.94 main [1] 0.05 0.50 100000/100000 CMatrixMulDouble(double, std::vector<std::complex<double>, std::allocator<std::complex<double> > >&) [2] 0.03 0.28 100000/100000 CMatrixDiagMul(std::vector<std::complex<double>, std::allocator<std::complex<double> > >&, std::vector<std::complex<double>, std::allocator<std::complex<double> > >&, int, int, int) [5] 整個程序運行0.96s 0.94是由main的children貢獻的 其中CMatrixMulDouble貢獻了0.05+0.50 CMatrixDiagMul貢獻了0.03+0.28 [2] 56.9 0.05 0.50 100000 CMatrixMulDouble(double, std::vector<std::complex<double>, std::allocator<std::complex<double> > >&) [2] 0.01 0.36 1200000/1200012 std::vector<std::complex<double>, std::allocator<std::complex<double> > >::push_back(std::complex<double> const&) [3] CMatrixMulDouble用時0.05+0.50 其中0.01+0.36的時間都是push_back貢獻的 所以問題的根源就在push_back
SunShow机器人#4 · 2010/8/23
嗯,谢谢。原来push_back这么耗时呀 【 在 ericyosho 的大作中提到: 】 : 前面那个函数,没循环一次,都要进行函数的调用。 : vB.size()还有push_back : 后面那个函数,没有函数调用,一开始都把空间分配好了。 : ...................
SunShow机器人#5 · 2010/8/23
谢谢你如此详细的分析。我也发现是push_back的问题了。 麻烦问一下,怎么看出来这些耗时呢?以前从没见过这种分析方式 【 在 guo 的大作中提到: 】 : granularity: each sample hit covers 2 byte(s) for 1.04% of 0.96 seconds : index % time self children called name : <spontaneous> : ...................
zxsword机器人#6 · 2010/8/23
好崇拜会C++的呀=。=
SunShow机器人#7 · 2010/8/23
额,我查了一下,貌似是Linux 下的 Gnu gprof吧。看来Linux 还真有不错的工具呀... 【 在 guo 的大作中提到: 】 : granularity: each sample hit covers 2 byte(s) for 1.04% of 0.96 seconds : index % time self children called name : <spontaneous> : ...................
guo机器人#8 · 2010/8/24
這話說的 Linux當然有很多很好的工具~~ 【 在 SunShow 的大作中提到: 】 : 额,我查了一下,貌似是Linux 下的 Gnu gprof吧。看来Linux 还真有不错的工具呀...