【问题标题】:С++ why is an array at least 32% faster than a vector? [closed]С++ 为什么数组比向量至少快 32%? [关闭]
【发布时间】:2021-05-06 18:23:36
【问题描述】:

例如我们有一系列数字 [0, 1, 2, ... N]
我们需要以相反的顺序排列它们 [N, ... 2, 1, 0]
使用数组还是向量更好?
如果我们使用向量,那么使用“交换”还是使用缓冲区?

使用“交换”:

for (int i = 0; i < NUMBS / 2; i++)
        std::swap(vec[i], vec[(NUMBS - 1) - i]);

使用缓冲区:

int buf;
for (int i = 0; i < NUMBS / 2; i++) {
    buf = vec[i];
    vec[i] = vec[(NUMBS - 1) - i];
    vec[(NUMBS - 1) - i] = buf;
}

我写了一个小代码来证明在这个任务中数组比向量更快:

#include <iostream>
#include <vector>
#include <chrono>
#include <algorithm>
#include <cmath>

#define NUMBS 20000000

std::vector<int> vec;
int arr[NUMBS];

float timeVswap;
float timeVbuf;
float timeAbuf;

class Timer {
private:
    using clock_t = std::chrono::high_resolution_clock;
    using second_t = std::chrono::duration<double, std::ratio<1> >;

    std::chrono::time_point<clock_t> m_beg;

public:
    Timer() : m_beg(clock_t::now()) {
    }

    void reset() {
        m_beg = clock_t::now();
    }

    double elapsed() const {
        return std::chrono::duration_cast<second_t>(clock_t::now() - m_beg).count();
    }
};

void Vswap() {
    Timer t;
    t.reset();

    for (int i = 0; i < NUMBS / 2; i++)
        std::swap(vec[i], vec[(NUMBS - 1) - i]);

    timeVswap = t.elapsed();
}

void Vbuf() {
    Timer t;
    t.reset();

    int buf;
    for (int i = 0; i < NUMBS / 2; i++) {
        buf = vec[i];
        vec[i] = vec[(NUMBS - 1) - i];
        vec[(NUMBS - 1) - i] = buf;
    }

    timeVbuf = t.elapsed();
}

void Abuf() {
    Timer t;
    t.reset();

    int buf;
    for (int i = 0; i < NUMBS / 2; i++) {
        buf = arr[i];
        arr[i] = arr[(NUMBS - 1) - i];
        arr[(NUMBS - 1) - i] = buf;
    }

    timeAbuf = t.elapsed();
}

int main() {
    Timer t;

    for (int i = 0; i < NUMBS; i++) {
        vec.push_back(i);
        arr[i] = i;
    }

    Vswap();
    Vbuf();
    Abuf();

    std::cout << "Time for vector (swap):   " << timeVswap << " sec.\n";
    std::cout << "Time for vector (buf):    " << timeVbuf << " sec.\n";
    std::cout << "------------------------------------\n";
    std::cout << "Time for array (buf):     " << timeAbuf << " sec.\n";
    std::cout << "\n";
    std::cout << "array is faster: " << floorf(100 - timeAbuf / timeVbuf * 100) << " %\n";

    return 0;
}

我得到了这样的结果:

【问题讨论】:

  • 与以往的基准测试问题一样,您使用哪些优化标志进行编译?
  • 使用数组还是向量更好?” - 自己衡量一下,看看哪个更适合您的用例。 “如果我们使用向量,那么使用“交换”还是使用缓冲区?” - 考虑使用std::reverse(),例如:std::reverse(vec.begin(), vec.end()); ... std::reverse(arr, arr+NUMBS);
  • 看这里当你打开优化时会发生什么:godbolt.org/z/nczx3j1ej。但是,请注意结果没有那么有意义,因为编译器可能会优化代码中的大多数计算,您需要使用结果来确保不会发生这种情况。不幸的是,微基准测试并不是那么容易
  • array is faster: -2 % :)
  • 注意:high_resolution_clock 是......麻烦。 Even it's creator recommends that you not use it.

标签: c++ arrays vector


【解决方案1】:

С++ 为什么数组至少比向量快 32%?

不是。

您没有打开编译器优化,因此您的结果不能代表std::vector comares 在实际应用程序中的排列方式。

通过-O3 使用 gcc 开启优化后,我得到了输出:

array is faster: -2 %

在另一次运行中:

Time for vector (swap):   0.0100716 sec.
Time for vector (buf):    0.00857671 sec.
------------------------------------
Time for array (buf):     0.00842298 sec.

array is faster: 1 %

请注意,绝对时间很小。这暗示编译器意识到当它实际上没有对向量和数组进行任何交换或反转时,它没有可观察到的效果。您必须使用计算结果来确保编译器不会优化您实际想要测量的内容。

【讨论】:

  • 好的! “向量时间(交换):0.0100716 秒。”为什么这么大?
  • @SerhiiOleksenko 为什么是“大”?你测量的时间是0.17001 sec
  • 您的交换速度降低了 15%:0.0100716 秒。缓冲区:0.00857671 秒。
  • 如果你说话时间短,加 2 - 3 个零 -> #define NUMBS 2000000000
  • @SerhiiOleksenko 我使用了您在问题中报告的内容#define NUMBS 20000000
猜你喜欢
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 2013-10-03
  • 1970-01-01
  • 2010-12-28
相关资源
最近更新 更多