为什么std :: vector比数组慢?

时间:2020-02-19 05:30:50

标签: c++ arrays vector benchmarking

当我运行以下程序(启用优化)时,带有for的{​​{1}}循环大约需要0.04秒,而带有数组的std::vector循环则需要0.0001秒。

for

该代码是我在编写raycaster时遇到的性能问题的简化版本。 #include <iostream> #include <vector> #include <chrono> int main() { int len = 800000; int* Data = new int[len]; int arr[3] = { 255, 0, 0 }; std::vector<int> vec = { 255, 0, 0 }; auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < len; i++) { Data[i] = vec[0]; } auto finish = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> elapsed = finish - start; std::cout << "The vector took " << elapsed.count() << "seconds\n"; start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < len; i++) { Data[i] = arr[0]; } finish = std::chrono::high_resolution_clock::now(); elapsed = finish - start; std::cout << "The array took " << elapsed.count() << "seconds \n"; char s; std::cin >> s; delete[] Data; } 变量对应于原始程序中的循环需要运行多少次(400像素* 400像素* 50最大渲染距离)。由于复杂的原因(也许我不太了解如何使用数组),我必须在实际的raycaster中使用向量而不是数组。但是,正如该程序演示的那样,每秒只能给我20帧,而使用数组应该给我的每秒10,000帧令人羡慕(显然,这只是一个简化的性能测试)。但是,不管这些数字有多准确,我仍然想尽可能地提高帧速率。那么,为什么矢量的执行速度比数组慢得多?有没有办法加快速度?谢谢你的帮助。如果我还有其他奇怪的事情可能会影响性能,请告诉我。在研究此问题的答案之前,我什至不知道优化,因此,如果还有更多类似的事情可能会提高性能,请告诉我(如果您解释了这些设置在哪里,希望您能告诉我。)属性管理器而不是命令行,因为我还不知道如何使用命令行)

2 个答案:

答案 0 :(得分:1)

让我们观察how GCC optimizes this test program

#include <vector>

int main()
{
    int len = 800000;
    int* Data = new int[len];

    int arr[3] = { 255, 0, 0 };
    std::vector<int> vec = { 255, 0, 0 };

    for (int i = 0; i < len; i++) {
        Data[i] = vec[0];
    }
    for (int i = 0; i < len; i++) {
        Data[i] = arr[0];
    }
    delete[] Data;
}

编译器正确地注意到向量是常数,然后将其消除。这两个循环生成的代码完全相同。因此,第一个循环使用数组还是向量应该无关紧要。

.L2:
    movups  XMMWORD PTR [rcx], xmm0
    add     rcx, 16
    cmp     rsi, rcx
    jne     .L2

使测试程序与众不同的是循环的顺序。注释指出when a third loop is added to the beginning,两个循环花费相同的时间。

我希望使用现代编译器,在启用优化和禁用调试的情况下,访问向量的速度几乎与访问数组一样快。如果您的实际程序中有明显的差异,则问题出在其他地方。

答案 1 :(得分:-1)

关于缓存。我不知道它的详细工作原理,但是Data[]在使用过程中被cpu更好地了解。如果颠倒计算顺序,您会看到“向量更快”。

但是实际上,您既没有测试vector也没有测试array。假设vec[0]位于0x01的存储位置,arr[0]位于0xf1。唯一的区别是从不同的单个内存地址读取单词。因此,您正在测试如何为动态分配的array的元素分配一个值

注意: std::chrono::high_resolution_clock可能不足以测量刻度线。最好像cppreference所说的那样使用steady_clock