【问题标题】:std::vector vs std::array performancestd::vector 与 std::array 性能
【发布时间】:2012-08-25 10:06:44
【问题描述】:

我正在查看新的 chrono 库 (C++11) 并尝试使用它。我写了以下两个程序:

vector.cpp

#include <iostream>
#include <vector>
#include <chrono>

int main()
{
    std::vector<double> vector(1000000, 0.);

    auto start = std::chrono::high_resolution_clock::now();
    for(int i(0); i < vector.size(); i++)
    {
        vector[i] += 1.;
    }
    auto end = std::chrono::high_resolution_clock::now();

    std::cout << "Elapsed time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() << " milliseconds" << std::endl;

    return 0;
}

array.cpp

#include <iostream>
#include <array>
#include <algorithm>
#include <chrono>

int main()
{
    std::array<double, 1000000> array;

    std::fill(array.begin(), array.end(), 0.);

    auto start = std::chrono::high_resolution_clock::now();
    for(int i(0); i < array.size(); i++)
    {
        array[i] += 1.;
    }
    auto end = std::chrono::high_resolution_clock::now();

    std::cout << "Elapsed time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() << " milliseconds" << std::endl;

    return 0;
}

我为数组程序获得了 9 毫秒,为向量程序获得了 12 毫秒。 std::vector 似乎比 std::array 慢 33%。我做得对吗?为什么会有这种差异?

Ps:我使用的是 GCC 4.7,Mac OS X 10.7。

g++-mp-4.7 -std=c++11 vector.cpp -o vector
g++-mp-4.7 -std=c++11 array.cpp -o array

【问题讨论】:

  • 更改为for(int i(0), iMax( vector.size() ); i &lt; iMax; i++)
  • 您是否运行了足够多的时间以确保您的时间在统计上是准确的? - 1 次运行 3 毫秒的差异可能没有意义。
  • @R.M.,以确保您不会在每次迭代中做任何额外的工作 - 您应该为两个版本都做。
  • 顺便说一句,您不需要std::fill 将数组归零,您可以像这样初始化它std::array&lt;double, 1000000&gt; array{}
  • 你也应该打开优化,否则这个练习完全是学术性的。

标签: c++ performance c++11 chrono


【解决方案1】:

我将您的代码更改为:

std::array<double, 1000000> array;

double total = 0;
std::fill(array.begin(), array.end(), 0.);

for (unsigned j = 0; j < 1000; ++j)
{
    auto start = std::chrono::high_resolution_clock::now();

    for (unsigned i = 0; i < array.size(); i++)
    {
        array[i] += 1.;
    }

    auto end = std::chrono::high_resolution_clock::now();
    total = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

std::cout << total << " for Array." << std::endl;

std::vector<double> vector(1000000, 0.);
total = 0;

for (unsigned j = 0; j < 1000; ++j)
{
    auto start = std::chrono::high_resolution_clock::now();

    for (unsigned i = 0; i < vector.size(); i++)
    {
        vector[i] += 1.;
    }

    auto end = std::chrono::high_resolution_clock::now();
    total = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

std::cout << total << " for Vector." << std::endl;

我使用-O3的结果:

8123 for Array.
8117 for Vector.

在我看来,两者都同样快。

【讨论】:

  • 我确认您的结果(使用 O3 选项):Array 为 3005。 3018 为向量。 10000 次循环:30103 用于阵列。 30082 表示向量。
【解决方案2】:

如果不启用优化,这些数字毫无意义。对 size() 的重复调用很可能会对您的情况产生影响。

【讨论】:

    【解决方案3】:

    std::array 的大小在编译时是已知的,因此很可能会在堆栈上分配内存。

    std::vector 使用 std::allocator(它可能使用 `new 在运行时从空闲存储区(又名堆)分配内存)。

    我会说 30% 对于堆与堆栈分配是正常的。


    编辑: 在 liveworkspace.org(std::vectorstd::array)上运行几次(我知道这不是最科学的测量),我得到 8 对 10 毫秒。由于所有分配确实超出了测量范围,我会天真地得出结论,访问堆比访问堆栈内存要慢。如果这通常是正确的,我不会感到惊讶,因为在堆的情况下存在额外的间接性。

    【讨论】:

    • 所有分配都发生在计时窗口之外。
    • 它显然没有在堆栈上分配 1M 双精度 - 再猜一次。
    • @lucas1024 所以你认为std::array 知道堆栈以外的任何事情?
    猜你喜欢
    • 2012-06-30
    • 2011-05-24
    • 2010-09-19
    • 1970-01-01
    • 2015-07-27
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    相关资源
    最近更新 更多