Warum ist std :: vector :: operator [] 5- bis 10-mal schneller als std :: vector :: at ()?

Während der Programmoptimierung, als ich versuchte, eine Schleife zu optimieren, die einen Vektor durchläuft, fand ich die folgende Tatsache: :: std :: vector :: at () ist EXTREM langsamer als operator []!

Der Operator [] ist 5- bis 10-mal schneller als at (), sowohl in Release- als auch in Debug-Builds (VS2008 x86).

urch ein bisschen Lesen im Web wurde mir klar, dass at () eine Grenzüberprüfung hat. Ok, aber die Operation um das Zehnfache verlangsamen?!

Gibt es einen Grund dafür? Ich meine, die Grenzüberprüfung ist ein einfacher Zahlenvergleich, oder fehlt mir etwas?
Die Frage ist, was ist der wahre Grund für diesen Performance-Hit?
Außerdem,ibt es eine Möglichkeit, es noch schneller zu mache?

Ich werde auf jeden Fall alle meine at () -Aufrufe mit [] in anderen Codeteilen tauschen (in denen ich bereits eine benutzerdefinierte Grenzüberprüfung habe!).

Konzeptioneller Beweiß

#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;
}

Bearbeiten
Jetzt wird der Wert "xyz" zugewiesen, damit der Compiler ihn nicht "auslöscht".

Antworten auf die Frage(6)

Ihre Antwort auf die Frage