¿Por qué es std :: vector :: operator [] de 5 a 10 veces más rápido que std :: vector :: at ()?

Durante la optimización del programa, tratando de optimizar un ciclo que itera a través de un vector, descubrí el siguiente hecho: :: std :: vector :: at () ¡es EXTREMADAMENTE más lento que el operador []!

El operador [] es de 5 a 10 veces más rápido que en (), tanto en versiones de lanzamiento y depuración (VS2008 x86).

Leer un poco en la web me hizo darme cuenta de que at () tiene verificación de límites. Ok, pero, ¿ralentizar 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 de números, ¿o me falta algo?
La pregunta es ¿cuál es la verdadera razón de este éxito en el rendimiento?
Además,¿Hay alguna manera de hacerlo aún más rápido??

Ciertamente voy a intercambiar todas mis llamadas a () con [] en otras partes del código (¡en las que ya tengo una verificación de límites 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 el valor se asigna a "xyz", por lo que el compilador no lo "borrará".

Respuestas a la pregunta(3)

Su respuesta a la pregunta