Warum würde die Karte viel schneller als unordered_map?
Implementiert habe ich eine Suche Zwischenspeicherung von Ergebnissen, die aus Schlüsseln bestehen von Art Zustand (a-Klasse mit 7 short ints), und Werte des Typs Socre (eine Klasse von 3 verdoppelt.) Mit unordered_map war mindestens 20 mal langsamer als eine Karte. Warum?
Edit: so ein Mist! Meine hash-Funktion wurde
namespace std {
size_t hash<State>::operator()(State const& s) const {
size_t retval = hash<short>()(s.s[0]);
for (int i = 1; i < R; i += 2) { //1 3 5
int x = (static_cast<int>(s.s[i + 1]) << 16)
+ (static_cast<int>(s.s[i]));
hash_combine(retval, x);
}
}
}
Ich vergaß zu return retval
, also es war alles kollidieren! Ich Wünsche unordered_map hatte hash_function_quality () - Funktion, die Berichte die Durchschnittliche Anzahl von Kollisionen.
- Was ist Ihr Zugang Muster?
- Welche Plattform/compiler?
- intel i5, gcc, 6 hundert tausend Einsätzen und lookups
- Verwenden Sie eine hash-Funktion mit unordered_map?
- ja. würde es funktionieren, wenn ich nicht?
- Für sechs-hundert-tausend-Einsätzen würde ich wahrscheinlich ein
std::map
noch. Es ist nur etwa 19 Operationen, um den Zugriff auf ein element. Jeder computer führt die 19-Operationen sehr schnell. Auch die prototypische Computer aus den 1950er Jahren. - Es war tatsächlich UB zu fallen das Ende eines Wert-Rückkehr-Funktion. Gcc hat eine Warnung für diese, -Wreturn-Typ, die in die Wand.
- Der compiler nutze ich, gibt ein lautes Warnsignal, wenn eine Funktion nicht wieder etwas am Ende. Nicht deins?
- Ich verwende cmake und ich denke, es ist verstecken Sie die Warnhinweise.
- Genial. Sie herausgefunden, wie man cmake als IDE.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Geschwindigkeit der unordered_map ist direkt proportional zu der Geschwindigkeit der Hash-Funktion. Es ist nie einfach eine Beziehung. Case in point, wenn Sie sich für die einfachste Hash-Funktion:
dann, was werden Sie am Ende mit ist eine Sammlung, die sich verhält wie eine Liste eher als eine Hash-container. Alle Elemente anzeigen, um eine einzelne Eimer und müssen Sie durchqueren den gesamten Eimer, bis Sie das Einzelteil, das Sie wünschen (etwas dauern könnte O(N) Zeit.)
Was Sie tun müssen, ist, sich auf zwei Dinge:
Entweder von diesen selbst, kann und wird töten die Leistung.
std::unordered_map
ist allgemein langsam, für eine kleine Anzahl von Elementen, da die hash-Funktion. Es wird eine Feste (-ish) Höhe der Zeit, aber vielleicht eine erhebliche Menge an Zeit dennoch.std::map
auf der anderen Seite einfacher ist, alsstd::unordered_map
. Die Zeit, die es braucht, Zugriff auf ein element, es hängt von der Anzahl der Elemente, aber weniger als die Anzahl der Elemente wächst. Und die groß-oh-Faktorc
für eine std::map ist allgemein sehr klein, im Vergleich zustd::unordered_map
.Im Allgemeinen lieber mit
std::map
überstd::unordered_map
, es sei denn, Sie haben einen besonderen Grund zur Benutzungstd::unordered_map
. Dies gilt insbesondere, wenn Sie nicht über eine große Anzahl von Elementen.unordered_map
verwendet eine hash-Tabelle unter der Haube, so dass die meisten offensichtlichen Grund, warum hash-schlecht ist, weil Sie zu viele Kollisionen. Können Sie erwägen, verschiedene, nicht-Standard -, hash-Funktion, die geben bessere Ergebnisse für Ihre Art des keys.Für
Ich denke, dass die folgende Funktion hilfreich sein könnten.
Niedriger die
load_factor
besser ist die hash-Funktion.