から JDK-4045622 in dem Joshua Bloch die Gründe beschreibt, warum diese besondere (neue) String.hashCode()
Implementierung gewählt wurde
Die nachstehende Tabelle gibt einen Überblick über die Leistung der verschiedenen Hashwerte Funktionen für drei Datensätze zusammen:
1) Alle Wörter und Ausdrücke mit Einträgen in Merriam-Webster's 2nd Int'l Unabridged Dictionary (311.141 Zeichenfolgen, durchschnittliche Länge 10 Zeichen).
2) Alle Zeichenketten in /bin/ , /usr/bin/ , /usr/lib/ , /usr/ucb/ und /usr/openwin/bin/* (66.304 Zeichenfolgen, durchschnittliche Länge 21 Zeichen).
3) Eine Liste von URLs, die von einem Web-Crawler gesammelt wurden, der letzte Nacht mehrere Stunden lang lief Stunden lang lief (28.372 Zeichenfolgen, durchschnittliche Länge 49 Zeichen).
Die in der Tabelle angegebene Leistungskennzahl ist die "durchschnittliche Kettengröße" über alle Elemente in der Hashtabelle (d. h. der Erwartungswert der Anzahl der Schlüsselvergleiche zum Nachschlagen eines Elements).
Webster's Code Strings URLs
--------- ------------ ----
Current Java Fn. 1.2509 1.2738 13.2560
P(37) [Java] 1.2508 1.2481 1.2454
P(65599) [Aho et al] 1.2490 1.2510 1.2450
P(31) [K+R] 1.2500 1.2488 1.2425
P(33) [Torek] 1.2500 1.2500 1.2453
Vo's Fn 1.2487 1.2471 1.2462
WAIS Fn 1.2497 1.2519 1.2452
Weinberger's Fn(MatPak) 6.5169 7.2142 30.6864
Weinberger's Fn(24) 1.3222 1.2791 1.9732
Weinberger's Fn(28) 1.2530 1.2506 1.2439
Ein Blick auf diese Tabelle zeigt, dass alle Funktionen mit Ausnahme der Funktion die aktuelle Java-Funktion und die beiden kaputten Versionen von Weinbergers eine ausgezeichnete, nahezu ununterscheidbare Leistung bieten. I vermute stark, dass diese Leistung im Wesentlichen das "theoretische Ideal" ist, das man erreichen würde, wenn man einen echten Zufallsgenerator Zufallszahlengenerator anstelle einer Hash-Funktion verwenden würde.
Ich würde die WAIS-Funktion ausschließen, da ihre Spezifikation Seiten mit Zufallszahlen enthält und ihre Leistung nicht besser ist als die der weitaus einfacheren Funktionen. Jede der übrigen sechs Funktionen scheint ausgezeichnete Wahl, aber wir müssen uns für eine entscheiden. Ich denke, ich würde ausschließen Vo's Variante und Weinberger's Funktion ausschließen, weil sie zusätzlich Komplexität ausschließen, auch wenn sie gering ist. Von den verbleibenden vier Funktionen würde ich mich wahrscheinlich für P(31) wählen, da sie auf einer RISC-Maschine am einfachsten zu berechnen ist (weil 31 die Differenz von zwei Zweierpotenzen ist). P(33) ist ähnlich billig zu berechnen berechnen, aber die Leistung ist geringfügig schlechter, und 33 ist zusammengesetzt, was mich ein wenig nervös macht.
Josh
16 Stimmen
Wenn es 29 oder 37 oder sogar 97 wäre, würden Sie fragen: "Warum nicht 31?
3 Stimmen
@EJP es ist wichtig, den Grund für die Wahl einer Nummer zu kennen, es sei denn, die Nummer ist das Ergebnis eines schwarzen Zaubertricks.
0 Stimmen
Es gibt einen Blogbeitrag von @peter-lawrey darüber hier: vanilla-java.github.io/2018/08/12/ und hier: vanilla-java.github.io/2018/08/15/
1 Stimmen
@DushyantSabharwal Ich will damit sagen, dass es auch wurde 29 oder 37 oder 97 oder 41 oder viele andere Werte, ohne dass dies einen großen praktischen Unterschied macht. Wir haben 1976 37 verwendet.