C ++,实例化std :: vector时性能不佳

时间:2014-12-10 10:50:22

标签: c++ arrays performance vector stl

我有一个关于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。 这是免费软件;查看复制条件的来源。没有 保证;甚至不适用于适销性或特定用途的适用性。

1 个答案:

答案 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版本会在您读取内存时执行映射和初始化。