Das Einfügen in std :: unordered_map ruft die Hash-Funktion zweimal in MSVC ++s STL, schlechtem Design oder einem speziellen Grund auf?

9

Für diesen Code:

%Vor%

Bei der Verwendung von g ++ überrascht die Ausgabe nicht:

%Vor%

Aber die Ergebnisse von MSVC ++ (2015) schockierten mich:

%Vor%

Weitere Tests haben gezeigt, dass die STL von MSVC ++ die Hash-Funktion zweimal aufruft, wenn ein neues Element in die unordered_map eingefügt wird, und einmal, wenn das Element bereits in der Map enthalten ist.

Ich fühle mich ziemlich seltsam für dieses Verhalten, weil ich denke, dass das Cachen des Ergebnisses viel schneller ist, als die Hash-Funktion in den meisten Fällen erneut aufzurufen (wenn die Implementierung wirklich den Hash-Wert zweimal verwenden muss). Oder besser, ich denke, wir benutzen einfach die Hash-Funktion, um den Bucket für das Element zu finden, und die folgende Routine ist für den Hash-Wert nicht relevant.

Da die Autoren von STL jedoch viel erfahrener sind als ich in C ++, weiß ich nicht, ob sie besondere Gründe für diese Implementierung haben? Ist das nur ein schlechtes Design oder verursacht durch einige mir unbekannte Gründe?

    
James 21.11.2015, 02:35
quelle

2 Antworten

2

hat im Release-Modus das gleiche Verhalten mit VS2012 beobachtet.

Der Unterschied liegt in der Implementierung von un_orderedmap. Wenn Sie debuggen und in Microsoft Visual Studio 11.0 \ VC \ include \ unordered_map gehen, ist der erste Aufruf des Funktionsaufrufoperators, ob der Schlüssel bereits in der Map vorhanden ist. Der zweite Aufruf erfolgt während des Einfügens in die Karte (vorausgesetzt, der Schlüssel wurde nicht gefunden) - nach 3 Iterationen hat map ((0,1), (1,1), (2,1))

    
Nandu 21.11.2015 02:59
quelle
1

Nun, wenn wir 23.5.4.3 betrachten, scheint weder die Wirkung noch die Komplexitätsklausel zu erfordern, dass die Hash-Funktion nur einmal aufgerufen wird. Es scheint, dass beide Implementierungen, obwohl sie intuitiv seltsam sind, legal sind.

    
Mark B 21.11.2015 03:17
quelle

Tags und Links