के लिए सबसे अधिक कुशल यूनिकोड हैश फ़ंक्शन मुझे डेल्फी 200 में सबसे तेज़ हैश फ़ंक्शन की आवश्यकता है जो यूनिकोड स्ट्रिंग से हैश वैल्यू बनाएगा जो बाल्टी में काफी यादृच्छिक रूप से वितरित करेगा।डेल्फी 200
मैं मूल रूप से GpStringHash से Gabr के HashOf समारोह के साथ शुरू किया:
function HashOf(const key: string): cardinal;
asm
xor edx,edx { result := 0 }
and eax,eax { test if 0 }
jz @End { skip if nil }
mov ecx,[eax-4] { ecx := string length }
jecxz @End { skip if length = 0 }
@loop: { repeat }
rol edx,2 { edx := (edx shl 2) or (edx shr 30)... }
xor dl,[eax] { ... xor Ord(key[eax]) }
inc eax { inc(eax) }
loop @loop { until ecx = 0 }
@End:
mov eax,edx { result := eax }
end; { HashOf }
लेकिन मैंने पाया कि यह यूनिकोड तार से अच्छे नंबर नहीं मिला। मैं ने कहा कि Gabr की दिनचर्या डेल्फी 2009
तब के लिए अद्यतन नहीं किया गया है मैं डेल्फी 2009 के SysUtils में HashNameMBCS की खोज की और इस सरल कार्य करने के लिए यह अनुवाद (जहां "स्ट्रिंग" एक डेल्फी 2009 यूनिकोड स्ट्रिंग है):
function HashOf(const key: string): cardinal;
var
I: integer;
begin
Result := 0;
for I := 1 to length(key) do
begin
Result := (Result shl 5) or (Result shr 27);
Result := Result xor Cardinal(key[I]);
end;
end; { HashOf }
मैंने सोचा था कि जब तक मैं सीपीयू खिड़की को देखा और कोडांतरक कोड यह उत्पन्न देखा यह बहुत अच्छा था:
Process.pas.1649: Result := 0;
0048DEA8 33DB xor ebx,ebx
Process.pas.1650: for I := 1 to length(key) do begin
0048DEAA 8BC6 mov eax,esi
0048DEAC E89734F7FF call $00401348
0048DEB1 85C0 test eax,eax
0048DEB3 7E1C jle $0048ded1
0048DEB5 BA01000000 mov edx,$00000001
Process.pas.1651: Result := (Result shl 5) or (Result shr 27);
0048DEBA 8BCB mov ecx,ebx
0048DEBC C1E105 shl ecx,$05
0048DEBF C1EB1B shr ebx,$1b
0048DEC2 0BCB or ecx,ebx
0048DEC4 8BD9 mov ebx,ecx
Process.pas.1652: Result := Result xor Cardinal(key[I]);
0048DEC6 0FB74C56FE movzx ecx,[esi+edx*2-$02]
0048DECB 33D9 xor ebx,ecx
Process.pas.1653: end;
0048DECD 42 inc edx
Process.pas.1650: for I := 1 to length(key) do begin
0048DECE 48 dec eax
0048DECF 75E9 jnz $0048deba
Process.pas.1654: end; { HashOf }
0048DED1 8BC3 mov eax,ebx
यह Gabr के कोड से काफ़ी अधिक कोडांतरक कोड होता जा रहा है।
गति सार का है। क्या मैं कुछ भी लिख सकता हूं जो मैंने लिखा था पास्कल कोड या असेंबलर जो मेरा कोड उत्पन्न हुआ था?
अनुवर्ती।
अंततः मैं SysUtils.HashNameMBCS पर आधारित हैशऑफ फ़ंक्शन के साथ गया। ऐसा लगता है कि यूनिकोड तारों के लिए एक अच्छा हैश वितरण प्रदान करता है, और यह काफी तेज़ प्रतीत होता है।
हां, बहुत सारे असेंबलर कोड उत्पन्न हुए हैं, लेकिन डेल्फी कोड जो इसे उत्पन्न करता है, इतना आसान है और केवल बिट-शिफ्ट ऑपरेशंस का उपयोग करता है, इसलिए यह विश्वास करना मुश्किल है कि यह तेज़ नहीं होगा।
आपके अंतिम हैशऑफ में मुझे 1 से लंबाई (कुंजी) जाना चाहिए। – gabr
@gabr: धन्यवाद। अब मैं देखता हूं कि मैंने "फॉलोअप" लिखा है, यह भी महसूस नहीं किया कि मैं अपने प्रश्न के बारे में एक ही काम का उपयोग कर समाप्त हुआ, सिवाय इसके कि मैंने अपने अनुवर्ती में गलती की है। मैं इसे फिर से लिखूंगा। – lkessler