wykonywanie deklaracji obiektów
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
W pierwszej wersji kodu konstruktor i destruktor hashMap
nazywane są n
czasami, podczas gdy w drugiej wersji są wywoływane tylko raz.
Naturalnym pytaniem jest, dlaczego zniszczenie i zbudowanie nowego map
obiektu 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 map
kodu 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” map
opróż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ż map
pochodzi z _Tree
, jest wywoływane za każdym razem, gdy map
budowany jest obiekt.