我有一个关于std :: vector实例化的问题。我比较了std :: vector的实例化和相同大小的数组的动态分配。我期待std :: vector的实例化会花费更长的时间,但我的性能差异很大。
对于阵列我有53个我们 对于std :: vector,我有4338 us
我的代码:
#include <chrono>
#include <vector>
#include <iostream>
int main() {
unsigned int NbItem = 1000000 ;
std::chrono::time_point<std::chrono::system_clock> start, middle ,end;
start = std::chrono::system_clock::now() ;
float * aMallocArea = (float *)calloc(sizeof(float)*NbItem,0) ;
middle = std::chrono::system_clock::now() ;
std::vector<float> aNewArea ;
middle = std::chrono::system_clock::now() ;
aNewArea.resize(NbItem) ;
//float * aMallocArea2 = new float[NbItem];
end = std::chrono::system_clock::now() ;
std::chrono::duration<double> elapsed_middle = middle-start;
std::chrono::duration<double> elapsed_end = end-middle;
std::cout << "ElapsedTime CPU = " << elapsed_middle.count()*1000000 << " (us) " << std::endl ;
std::cout << "ElapsedTime CPU = " << elapsed_end.count()*1000000 << " (us) " << std::endl ;
free(aMallocArea) ;
return 0;
}
即使我创建了一个大小为0的向量,我也有这种差异。 你知道为什么我在实例化一个std :: vector时有这么糟糕的表现吗? 你知道如何改进这个(我尝试使用编译选项-O3,但它没有给出优秀的结果)。
编译行: g ++ --std = c ++ 11 -o test ./src/test.cpp
compilator版本: g ++ --version g ++(Debian 4.7.2-5)4.7.2 版权所有(C)2012 Free Software Foundation,Inc。 这是免费软件;查看复制条件的来源。没有 保证;甚至不适用于适销性或特定用途的适用性。
答案 0 :(得分:6)
你意识到这一点:
float * aMallocArea = (float *)calloc(sizeof(float)*NbItem, 0);
表示“分配大小为零的sizeof(float)*NbItem
个项目”?这意味着调用执行零字节分配。
即使你纠正了这一点,calloc
形式在很多情况下也会快得多。 calloc
实现能够“保留”内存域并返回指针。当您访问内存时,操作系统会映射虚拟内存。
另一方面,矢量实际上经过并初始化/构造其元素。没有实现我知道检查看到a)类型是POD,b)内存为零,以及c)分配器返回归零内存。因此,与calloc
相比,此初始化过程可能会花费相当多的时间。
所以“C”版本几乎没有(如果你修复你的程序),并且“C ++”版本通过,初始化每个元素,并触及分配中的所有内存。它会慢得多。
即使性能很重要,这也很少是支持C版本的理由。实际上,您应该只分配实际需要的内存。一旦你开始使用内存,时间就会消失(例如在C版本中,稍后访问它时需要时间来映射内存)。如果您 创建第二个定时测试(比方说)计算数组元素的平均值,那么C ++版本可能会在您的实现上更快,因为内存已经映射和初始化,而C版本会在您读取内存时执行映射和初始化。