Во время оптимизации программы, пытаясь оптимизировать цикл, который повторяет вектор, я обнаружил следующий факт: :: std :: vector :: at () НАМНОГО медленнее, чем operator []!
Оператор [] работает в 5-10 раз быстрее, чем при () , как в сборках выпуска, так и отладки (VS2008 x86).
Чтение в Интернете дало мне понять, что at () имеет проверку границ. Хорошо, но, замедляя работу в 10 раз?!
Есть ли причина для этого? Я имею в виду, проверка границ - это простое сравнение чисел или я что-то упустил?
Вопрос в том, что является реальной причиной этого удара производительности?
Более того, есть ли способ сделать это еще быстрее ?
Я, конечно, собираюсь поменять все мои вызовы at () с [] в других частях кода (в которых у меня уже есть пользовательская проверка границ!).
Подтверждение концепции:
#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:
Теперь значение присваивается «xyz», поэтому компилятор не будет «стирать» его.