可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
-
我在写一个CFD程序的时候碰到的问题,我想使用c++的特性把double数组封装成一个新的类,这样就可以重载运算符,像使用matlab那样直接进行矩阵层次的操作。
比如,在c++里要分别对元素操作:for(int i=0;i<10000;i++)C[i]=A[i]+B[i]
用matlab就可以直接写:
C=A+B;
但我写成一个类后,运算效率却比直接这样运行慢太多,甚至比matlab慢很多(C++应该比matlab快才对吧?)
比如如下代码:#include "pch.h" #include <iostream> #include <time.h> class Array { public: Array(int S):Size(S) //构造函数 { p = new double[Size]; } Array(int S, double n):Size(S) //构造函数 { p = new double[Size]; for (int i = 0; i < Size; i++)p[i] = n; } ~Array() //析构函数 { delete[] p; } Array & operator=(const Array & A) //重载= { if (this == &A) return *this; delete[] p; Size = A.Size; p = new double[Size]; memcpy(p, A.p, Size * sizeof(double)); return *this; } Array operator*(const Array & A) //对应元素* { Array result(Size); for (int i = 0; i < Size; i++)result.p[i] = p[i] * A.p[i]; return result; } private: int Size; double *p; }; int main() { clock_t time1, time2; Array A(10000, 1.0); Array B(10000, 1.0); Array C(10000, 1.0); time1 = clock(); for (int t = 0; t < 1000000; t++)C = A * B; time2 = clock(); std::cout<< "Time1 = " << (double)(time2 - time1) / CLOCKS_PER_SEC << "S" << std::endl; //测试直接使用double数组的速度 double a[10000]; double b[10000]; double c[10000]; for (int i = 0; i < 10000; i++)a[i] = 1, b[i] = 1; time1 = clock(); for (int t = 0; t < 1000000; t++) for (int i = 0; i < 10000; i++)c[i]=a[i] * b[i]; time2 = clock(); std::cout << "Time2 = " << (double)(time2 - time1) / CLOCKS_PER_SEC << "S" << std::endl; system("pause"); return 0; }
输出:
Time1 = 10.4S
Time2 = 0.492S
使用对象的时候慢了20多倍用matlab做相同工作的时候:
A=ones(10000,1); B=zeros(10000,1); t1=clock; for i=1:1000000 C=A.*B; end t2=clock; T=etime(t2,t1)
输出:
T =4.8610
我这样写是否犯了什么错误? 这种情况下应该如何提升c++的效率呢? -
谢谢您的回答!试了一下确实是编译器优化带来的问题,我在linux系统下使用g++编译这串代码,以下分别是优化等级-O0(无优化)、-O1、-O2、-O3时得到的运行速度:
-O0 Time1 = 47.759S Time2 = 29.2934S -O1 Time1 = 16.7366S Time2 = 4.35349S -O2 Time1 = 11.9593S Time2 = 1e-06S -O3: Time1 = 12.2002S Time2 = 0S
可见无优化时虽然我这种使用类的写法也要慢一些,但两者在一个数量级上,优化等级越高,直接使用数组的方法优势就越大了……
编译器的优化好神奇哦!
看来以后还是尽量去用别人写的成熟的函数库吧……