Durante la optimización del programa, tratando de optimizar un bucle que itera a través de un vector, encontré el siguiente hecho: :: std :: vector :: at() es EXTREMADAMENTE más lento que el operador []!¿Por qué std :: vector :: operator [] 5 a 10 veces más rápido que std :: vector :: at()?
El operador [] es de 5 a 10 veces más rápido que en(), tanto en la liberación de & versiones de depuración (x86 VS2008).
Al leer un poco en la web me di cuenta de que en() tiene una comprobación de límites. Ok, pero, ralentizando la operación hasta 10 veces?
¿Hay alguna razón para eso? Quiero decir, la verificación de límites es una simple comparación numérica, ¿o me falta algo?
La pregunta es, ¿cuál es el verdadero motivo de este golpe de rendimiento?
Además, ¿hay alguna manera de hacerlo aún más rápido?
Sin duda voy a intercambiar todas mis llamadas at() con [] en otras partes del código (en las que ya tengo una verificación de límite personalizada).
Prueba de concepto:
#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <conio.h>
#include <vector>
#define ELEMENTS_IN_VECTOR 1000000
int main()
{
__int64 freq, start, end, diff_Result;
if(!::QueryPerformanceFrequency((LARGE_INTEGER*)&freq))
throw "Not supported!";
freq /= 1000000; // microseconds!
::std::vector<int> vec;
vec.reserve(ELEMENTS_IN_VECTOR);
for(int i = 0; i < ELEMENTS_IN_VECTOR; i++)
vec.push_back(i);
int xyz = 0;
printf("Press any key to start!");
_getch();
printf(" Running speed test..\n");
{ // at()
::QueryPerformanceCounter((LARGE_INTEGER*)&start);
for(int i = 0; i < ELEMENTS_IN_VECTOR; i++)
xyz += vec.at(i);
::QueryPerformanceCounter((LARGE_INTEGER*)&end);
diff_Result = (end - start)/freq;
}
printf("Result\t\t: %u\n\n", diff_Result);
printf("Press any key to start!");
_getch();
printf(" Running speed test..\n");
{ // operator []
::QueryPerformanceCounter((LARGE_INTEGER*)&start);
for(int i = 0; i < ELEMENTS_IN_VECTOR; i++)
xyz -= vec[i];
::QueryPerformanceCounter((LARGE_INTEGER*)&end);
diff_Result = (end - start)/freq;
}
printf("Result\t\t: %u\n", diff_Result);
_getch();
return xyz;
}
Editar:
Ahora se está assiged el valor a "xyz", por lo que el compilador no "borrar" a cabo.
Tal vez en realidad se debe hacer algo con los elementos en lugar de sólo les pedía o el compilador podría optimizar la basura. – schnaader
No te entendí. ¿Explique? – Poni
Intenta hacer algo como 'test_int + = vec [i]' en los bucles for. Como no está haciendo nada con el elemento vectorial, el compilador podría optimizarlo completamente. También vea la respuesta de Ben para esto. – schnaader