[英]C++, bad performance when instantiating a std::vector
我有一个关于std :: vector的实例化的问题。 我比较了std :: vector的实例化和相同大小的数组的动态分配。 我期望std :: vector的实例化会花费更长的时间,但是我在性能上有很大的不同。
对于数组,我有53 us对于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
编译器版本:g ++ --version g ++(Debian 4.7.2-5)4.7.2版权所有(C)2012自由软件基金会,公司。 请参阅复制条件的来源。 没有保修; 甚至不是出于适销性或针对特定目的的适用性。
您是否意识到:
float * aMallocArea = (float *)calloc(sizeof(float)*NbItem, 0);
意味着“分配sizeof(float)*NbItem
项的大小为零”? 这意味着该调用执行零字节分配。
即使您更正了此问题,在许多情况下, calloc
表单也会更快。 calloc
实现能够“保留”内存域并返回指针。 当您访问内存时,操作系统会映射虚拟内存。
另一方面,向量实际上会经过并初始化/构造其元素。 我知道没有实现可以检查a)类型为POD,b)内存为零以及c)分配器返回零内存的情况。 因此,与calloc
相比,此初始化过程可能要花很多钱。
因此,“ C”版本几乎什么也不做(如果您修复程序),“ C ++”版本可以通过,初始化每个元素并触摸分配中的所有内存。 它将慢很多。
即使在性能很重要的情况下,也很少有理由支持C版本。 实际上,您应该只分配实际需要的内存。 一旦你开始使用的东西内存,时间将拉平(在C版本例如,它需要一定的时间,当您日后访问来映射内存)。 如果您要创建第二个计时测试,(说)计算的阵列元素的平均,C ++版本可能会更快您的实现,因为内存已被映射和初始化,而C版本将执行映射和初始化当您读取内存时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.