Почему std :: vector :: operator [] в 5-10 раз быстрее, чем std :: vector :: at ()?

Во время оптимизации программы, пытаясь оптимизировать цикл, который выполняет итерацию по вектору, я обнаружил следующий факт: :: 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;
}

Редактировать:
Теперь значение присваивается «xyz», поэтому компилятор не будет «стирать» его.

Ответы на вопрос(3)

Ваш ответ на вопрос