¿Cuál es la forma más rápida de restablecer todos los valores de a std::vector<int>
a 0 y mantener el tamaño inicial de los vectores?
¿Un bucle for con el operador []?
¿Cuál es la forma más rápida de restablecer todos los valores de a std::vector<int>
a 0 y mantener el tamaño inicial de los vectores?
¿Un bucle for con el operador []?
Respuestas:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) parece un poco más rápido que fill
en mi máquina
assign
.
Como siempre cuando preguntas sobre el más rápido: ¡Mide! Usando los métodos anteriores (en una Mac usando 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 |
usando 100000 iteraciones en un vector de 10000 ints.
Editar: si el cambio de estos números cambia de manera plausible los tiempos resultantes, puede tener cierta confianza (no tan buena como la inspección del código de ensamblaje final) de que el punto de referencia artificial no se ha optimizado por completo. Por supuesto, lo mejor es ensuciar el rendimiento en condiciones reales. fin Editar
para referencia el código usado:
#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;
}
Conclusión: ¡ uso std::fill
(porque, como otros han dicho, es lo más idiomático)!
assign
es más lento, excepto para pequeñas capacidades en libc++
. CÓDIGO coliru / paste
fill
ve terrible. Es dos órdenes de magnitud más lento en esta prueba.
¿Qué hay de la assign
función miembro?
some_vector.assign(some_vector.size(), 0);
Si es solo un vector de enteros, primero probaría:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
No es muy C ++, así que estoy seguro de que alguien proporcionará la forma adecuada de hacerlo. :)
::std::fill
método se expande a algo que es bastante rápido, aunque un poco en el lado del código, ya que todo está en línea. Sin embargo, todavía lo usaría porque es mucho más agradable de leer.
Tenía la misma pregunta pero bastante corta vector<bool>
(afaik el estándar permite implementarlo internamente de manera diferente que solo una matriz continua de elementos booleanos). Por lo tanto, repetí las pruebas ligeramente modificadas de Fabio Fracassi. Los resultados son los siguientes (tiempos, en segundos):
-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
Entonces, aparentemente para estos tamaños, vector<bool>::assign()
es más rápido. El código utilizado para las pruebas:
#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;
}
Usé el compilador GCC 7.2.0 en Ubuntu 17.10. La línea de comando para compilar:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp