2013-03-28 9 views
5

Poprosiłem o metodę similar question dla metody string.GetHashCode() w .NET. Od tego momentu dowiedziałem się, że nie możemy polegać na niejawnej implementacji kodu skrótu dla typów wbudowanych, jeśli mamy go używać na różnych maszynach. Dlatego zakładam, że implementacja Javy String.hashCode() jest również niestabilna w różnych konfiguracjach sprzętowych i może zachowywać się inaczej w maszynach wirtualnych (nie zapomnij o różnych implementacjach maszyn wirtualnych).Stabilność Java i string.hashCode() na komputerach w klastrze

Obecnie omawiamy sposób bezpiecznego przekształcenia ciągu w liczba w Javie, przez mieszanie, ale algorytm mieszania musi być stabilny w różnych węzłach klastra i powinien być szybki do oceny, ponieważ wystąpi wysoka częstotliwość użycia. Moi koledzy z drużyny nalegają na natywną metodę hashCode i potrzebuję pewnych rozsądnych argumentów, aby zmusić ich do ponownego rozważenia innego podejścia. Obecnie mogę myśleć tylko o różnicach między konfiguracjami maszyn (x86 i x64), ewentualnie różnymi dostawcami JVM na niektórych maszynach (prawie nie ma to zastosowania w naszym przypadku) i różnicami w kolejności bajtów, w zależności od maszyny, której algorytm jest używany. biegać. Oczywiście, należy również rozważyć kodowanie znaków.

Podczas gdy wszystkie te rzeczy przychodzą mi do głowy, nie jestem w 100% pewny, czy któryś z nich jest wystarczająco mocny, i byłbym wdzięczny za fachowość i doświadczenie w tej dziedzinie. Pomoże mi to zbudować mocniejsze argumenty na rzecz pisania niestandardowego algorytmu mieszania. Ponadto, doceniłbym porady dotyczące tego, co nie robić podczas implementacji.

+1

Kod hashcode jest dobrze zdefiniowany i taki sam na dowolnej platformie Java. – ZhongYu

+1

http://stackoverflow.com/questions/785091/consistency-of-hashcode-on-a-java-string – zch

+0

@ zhong.j.yu zakładasz [JRockit] (http://www.oracle.com /technetwork/middleware/jrockit/overview/index.html) i [IBM JVM] (http://publib.boulder.ibm.com/infocenter/java7sdk/v7r0/index.jsp? topic =% 2Fcom.ibm.java.lnx.70.doc% 2Fuser% 2Fjava_jvm.html) mają tę samą implementację dla 'String # hashCode'. –

Odpowiedz

11

Realizacja String.hashCode() jest specified w dokumentacji, więc jest to gwarancją spójne:

Kod skrótu dla obiektu String jest obliczana jako

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

użyciu int arytmetyczne, gdzie s [i] jest łańcuchem znaków, n jest długością łańcucha, a^wskazuje na potęgowanie. (Wartość mieszania pustego ciągu wynosi zero.)

Wszystkie te operacje są realizowane niezależnie dla platformy platformy Java - kolejność bajtów platformy nie ma na przykład znaczenia.

Mimo to, sposoby uzyskiwanie a String może być trudne, jeśli otrzymujesz go z pliku lub innego źródła bajtów. W takim przypadku wszystko jest w porządku, o ile wyraźnie określono numer Charset. (Pamiętaj, że String s nie mają inne kodowanie per se; kodowanie jest specyfikacją konwersji między byte[] i String).

+0

Jeśli chodzi o specyfikację (i składniki core java, które znam DO), to wydaje się, że jest wystarczająco bezpieczny. Dzięki –

3

Można spojrzeć na sourcecode, also shown below. Z tego, co widzę (po wszystkich 10 sekundach analizy), powinno to być stabilne na maszynach i architekturach. Louis potwierdza to, powołując się na specyfikację, jeszcze lepiej, jeśli wierzysz w specyfikacje. :-)

Jednak może to się różnić, jeśli inny JRE zdecyduje się go inaczej wdrożyć i naruszyć specyfikację.

public int hashCode() { 
    int h = hash; 
    if (h == 0) { 
     int off = offset; 
     char val[] = value; 
     int len = count; 

     for (int i = 0; i < len; i++) { 
      h = 31*h + val[off++]; 
     } 

     hash = h; 
    } 

    return h; 
} 
+0

Dziękuję za odpowiedź. Sam sprawdzałem kod źródłowy i nie znalazłem niczego, co mogłoby stanowić problem. Coś mi mówi, że to nie jedyne miejsce, w którym coś może pójść nie tak. Mamy nadzieję, że różne maszyny JVM (różni dostawcy) w tym samym klastrze nie będą dla nas problemem. –

+1

Sądzę, że jeśli sprzedawca łamie specyfikację, można uruchomić kilka znanych ciągów i porównać z oficjalnymi wynikami. Upewnij się, że uruchomiłeś kilka _tych. W początkach Javy metoda hashCode uwzględniała tylko 16 pierwszych (może 32?) Znaków. Widziałem sprzedawcę próbującego wygrać benchmark, robiąc podobne. – user949300

+0

Dobra rada, dziękuję za podzielenie się nią. Wierzę, że w obecnej sytuacji będziemy trzymać się JVM Oracle, chociaż ta wiedza może okazać się całkiem użyteczna pewnego dnia. Mając przemyślenia na ten temat, taki "wzrost wydajności" może kosztować wiele niepożądanych i nieprzewidywalnych zachowań. Zastanawiam się, czy dany dostawca JVM mógłby należeć do tej kategorii –

Powiązane problemy