std::vector<int>
のすべての値を0にリセットし、ベクトルの初期サイズを維持する最速の方法は何ですか?
[]演算子を使用したforループ?
std::fill(v.begin(), v.end(), 0);
いつものように最速について尋ねるとき:測定!上記の方法の使用(Clangを使用するMac):
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 intのベクトルで100000回の繰り返しを使用します。
編集:この数値を変更すると、結果の時間をもっともらしく変更できる場合、someの信頼を得ることができます(最終アセンブリの検査ほど良くありません)コード)人工的なベンチマークが完全に最適化されていないこと。もちろん、実際の条件下でパフォーマンスを測定することをお勧めします。 編集の終了
参考のために使用コード:
#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);
それが単なる整数のベクトルである場合、私は最初に試してみます:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
それはあまりC++ではないので、誰かがこれを行う適切な方法を提供すると確信しています。 :)
試してみる
std::fill
そしてまた
std::size siz = vec.size();
//no memory allocating
vec.resize(0);
vec.resize(siz, 0);
私は同じ質問をしましたが、かなり短いvector<bool>
(標準では、ブール要素の単なる連続配列とは異なる方法で内部的に実装することができます)。そのため、ファビオ・フラカッシによるわずかに修正されたテストを繰り返しました。結果は次のとおりです(時間、秒単位)。
-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