During program optimization, trying to optimize a loop that iterates through a vector, I found the following fact: ::std::vector::at() is EXTREMELY slower than operator[] !
The operator[] is 5 to 10 times faster than at(), both in release & debug builds (VS2008 x86).
Reading a bit on the web got me to realize that at() has boundary checking. Ok, but, slowing the operation by up to 10 times?!
Is there any reason for that? I mean, boundary checking is a simple number comparison, or am I missing something?
The question is what is the real reason for this performance hit?
Further more, is there any way to make it even faster?
I'm certainly going to swap all my at() calls with [] in other code parts (in which I already have custom boundary check!).
Proof of concept:
#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;
}
Edit:
Now the value is being assiged to "xyz", so the compiler will not "wipe" it out.