Was ist der schnellste Weg, um jeden Wert von a std::vector<int>
auf 0 zurückzusetzen und die anfängliche Größe der Vektoren beizubehalten?
Eine for-Schleife mit dem Operator []?
Was ist der schnellste Weg, um jeden Wert von a std::vector<int>
auf 0 zurückzusetzen und die anfängliche Größe der Vektoren beizubehalten?
Eine for-Schleife mit dem Operator []?
Antworten:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) scheint etwas schneller zu sein als fill
auf meinem Computer
assign
.
Wie immer, wenn Sie nach dem schnellsten fragen: Messen! Verwenden der oben genannten Methoden (auf einem Mac mit 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 |
Verwenden von 100000 Iterationen auf einem Vektor von 10000 Ints.
Edit: Wenn changeing diese Zahlen plausibel die resultierenden Zeiten ändert können Sie etwas Vertrauen (nicht so gut wie die Endmontage Code Inspektion) , dass die künstliche Benchmark nicht optimiert wurde entfernt vollständig. Natürlich ist es am besten, die Leistung unter realen Bedingungen zu beeinträchtigen. Ende Bearbeiten
als Referenz den verwendeten Code:
#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;
}
Fazit: verwenden std::fill
(weil, wie andere gesagt haben, es am idiomatischsten ist)!
assign
ist langsamer, mit Ausnahme kleiner Kapazitäten auf libc++
. CODE coliru / paste
fill
sieht das schrecklich aus. In diesem Test ist es zwei Größenordnungen langsamer.
Wie wäre es mit der assign
Mitgliedsfunktion?
some_vector.assign(some_vector.size(), 0);
Wenn es nur ein Vektor von ganzen Zahlen ist, würde ich zuerst versuchen:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
Es ist nicht sehr C ++, daher bin ich sicher, dass jemand den richtigen Weg dafür finden wird. :) :)
::std::fill
Methode erweitert sich zu etwas, das verdammt schnell ist, wenn auch etwas Code-aufgebläht, da alles inline ist. Ich würde es trotzdem benutzen, weil es viel schöner zu lesen ist.
Ich hatte die gleiche Frage, aber ziemlich kurz vector<bool>
(afaik erlaubt der Standard, sie intern anders zu implementieren als nur ein kontinuierliches Array von booleschen Elementen). Daher wiederholte ich die leicht modifizierten Tests von Fabio Fracassi. Die Ergebnisse sind wie folgt (Zeiten in Sekunden):
-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
Also anscheinend für diese Größen vector<bool>::assign()
ist schneller. Der für Tests verwendete Code:
#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;
}
Ich habe den GCC 7.2.0-Compiler unter Ubuntu 17.10 verwendet. Die Befehlszeile zum Kompilieren:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp