wykonywanie deklaracji obiektów

Jan 03 2021

Kodowałem na jakimś podboju uniwersyteckim i zauważyłem coś, kiedy deklarowałem mapę w pętli takiej jak poniżej:

for (int i = 0; i < n; i++)
{
    map<int, bool> hashMap;
    //...
}

zajmuje więcej czasu niż:

map<int, bool> hashMap;
for (int i = 0; i < n; i++)
{
    hashMap.clear();
    //...
}

więc zastanawiałem się, dlaczego zadeklarowanie obiektu w pętli ma gorszą wydajność niż zwykła ponowna inicjalizacja?

Odpowiedzi

2 dxiv Jan 04 2021 at 10:59

W pierwszej wersji kodu konstruktor i destruktor hashMapnazywane są nczasami, podczas gdy w drugiej wersji są wywoływane tylko raz.

Naturalnym pytaniem jest, dlaczego zniszczenie i zbudowanie nowego mapobiektu byłoby zauważalnie inne niż oczyszczenie i ponowne użycie tego samego obiektu. Ostateczna odpowiedź na to pytanie można uzyskać tylko poprzez sprawdzenie rzeczywistego mapkodu używanej implementacji, więc poniższe informacje są tylko prawdopodobnym przypuszczeniem.

std::mapjest zwykle implementowany przy użyciu czerwono-czarnych drzew , a implementacje drzew czerwono-czarnych często używają węzła wartowniczego dla liści NIL, patrz na przykład Korzyści z węzła wartowniczego w czerwono-czarnym drzewie? . Ten wartownik musi być przydzielany za każdym razem, gdy budowane jest drzewo, a następnie uwalniany po zniszczeniu. W przeciwieństwie do tego, clear„ing a” mapopróżnia drzewo, ale ponownie wykorzystuje powiązane obiekty wewnętrzne.

Aby zobaczyć przykład takiej implementacji z życia wzięty, _Treekonstruktor Microsoftu wywołuje metodę o trafnej nazwie _Alloc_sentinel_and_proxy();. Ponieważ mappochodzi z _Tree, jest wywoływane za każdym razem, gdy mapbudowany jest obiekt.