最快的方法重置std::vector<int>为0

std::vector<int>的每个值重置为0并保持向量初始大小的最快方法是什么?

使用[]操作符的for循环?

221148 次浏览

如果它只是一个整数向量,我首先尝试:

memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);

它不是很c++,所以我相信有人会提供正确的方式来做这件事。:)

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

试一试

std::fill

std::size siz = vec.size();
//no memory allocating
vec.resize(0);
vec.resize(siz, 0);

和往常一样,当你问最快的时候:Measure!使用上述方法(在Mac上使用Clang):

Method      |  executable size  |  Time Taken (in sec) |
|  -O0    |  -O3    |  -O0      |  -O3     |
------------|---------|---------|-----------|----------|
1. memset   | 17 kB   | 8.6 kB  | 0.125     | 0.124    |
2. fill     | 19 kB   | 8.6 kB  | 13.4      | 0.124    |
3. manual   | 19 kB   | 8.6 kB  | 14.5      | 0.124    |
4. assign   | 24 kB   | 9.0 kB  | 1.9       | 0.591    |

在10000个整数的向量上使用100000次迭代。

如果改变这些数字似乎改变了结果时间,你可以有一些信心(不如检查最终的汇编代码),人工基准测试没有完全优化掉。当然,最好是在真实条件下测量性能。 结束编辑< / >强

参考使用的代码:

#include <vector>


#define TEST_METHOD 1
const size_t TEST_ITERATIONS = 100000;
const size_t TEST_ARRAY_SIZE = 10000;


int main(int argc, char** argv) {


std::vector<int> v(TEST_ARRAY_SIZE, 0);


for(size_t i = 0; i < TEST_ITERATIONS; ++i) {
#if TEST_METHOD == 1
memset(&v[0], 0, v.size() * sizeof v[0]);
#elif TEST_METHOD == 2
std::fill(v.begin(), v.end(), 0);
#elif TEST_METHOD == 3
for (std::vector<int>::iterator it=v.begin(), end=v.end(); it!=end; ++it) {
*it = 0;
}
#elif TEST_METHOD == 4
v.assign(v.size(),0);
#endif
}


return EXIT_SUCCESS;
}

结论:使用std::fill(因为,正如其他人所说,它最习惯)!

assign成员函数呢?

some_vector.assign(some_vector.size(), 0);

我有同样的问题,但关于相当短的vector<bool> (afaik标准允许在内部实现它,而不仅仅是布尔元素的连续数组)。因此,我重复了Fabio Fracassi稍作修改的测试。结果如下(次数,单位:秒):

            -O0       -O3
--------  --------
memset     0.666     1.045
fill      19.357     1.066
iterator  67.368     1.043
assign    17.975     0.530
for i     22.610     1.004
显然,对于这些大小,vector<bool>::assign()更快。用于测试的代码:

#include <vector>
#include <cstring>
#include <cstdlib>


#define TEST_METHOD 5
const size_t TEST_ITERATIONS = 34359738;
const size_t TEST_ARRAY_SIZE = 200;


using namespace std;


int main(int argc, char** argv) {


std::vector<int> v(TEST_ARRAY_SIZE, 0);


for(size_t i = 0; i < TEST_ITERATIONS; ++i) {
#if TEST_METHOD == 1
memset(&v[0], false, v.size() * sizeof v[0]);
#elif TEST_METHOD == 2
std::fill(v.begin(), v.end(), false);
#elif TEST_METHOD == 3
for (std::vector<int>::iterator it=v.begin(), end=v.end(); it!=end; ++it) {
*it = 0;
}
#elif TEST_METHOD == 4
v.assign(v.size(),false);
#elif TEST_METHOD == 5
for (size_t i = 0; i < TEST_ARRAY_SIZE; i++) {
v[i] = false;
}
#endif
}


return EXIT_SUCCESS;
}
我在Ubuntu 17.10上使用GCC 7.2.0编译器。编译的命令行:

g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp