【发布时间】: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.