Quel est le moyen le plus rapide de réinitialiser chaque valeur d'un std::vector<int>
à 0 et de conserver la taille initiale du vecteur?
Une boucle for avec l'opérateur []?
std::fill(v.begin(), v.end(), 0);
Comme toujours lorsque vous posez la question la plus rapide: mesurez! Utilisation des méthodes ci-dessus (sur un Mac utilisant 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 |
en utilisant 100 000 itérations sur un vecteur de 10000 ints.
Edit: Si vous modifiez de manière plausible les temps résultants, vous pouvez avoir la certitude un peu _ (mais pas aussi bonne que l'inspection du code d'assemblage final) que le repère artificiel n'a pas été optimisé. Bien sûr, il est préférable d’envoyer les performances dans des conditions réelles . end Edit
pour référence le code utilisé:
#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;
}
Conclusion: utilise std::fill
(car, comme d'autres l'ont dit le plus idiomatique)!
Qu'en est-il de la fonction membre assign
?
some_vector.assign(some_vector.size(), 0);
Si c'est juste un vecteur d'entiers, je commencerai par essayer:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
Ce n'est pas très C++, donc je suis sûr que quelqu'un fournira la bonne façon de faire cela :)
essayer
std::fill
et aussi
std::size siz = vec.size();
//no memory allocating
vec.resize(0);
vec.resize(siz, 0);
J'avais la même question mais à propos de vector<bool>
plutôt court (autant que je sache, le standard permet de le mettre en œuvre en interne différemment d'un tableau continu d'éléments booléens). J'ai donc répété les tests légèrement modifiés de Fabio Fracassi. Les résultats sont les suivants (fois, en secondes):
-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
Donc, apparemment, pour ces tailles, vector<bool>::assign()
est plus rapide. Le code utilisé pour les tests:
#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;
}
J'ai utilisé le compilateur GCC 7.2.0 sur Ubuntu 17.10. La ligne de commande pour compiler:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp