2014-03-19 67 views
0

我正在計算Java和C#中的文本字符串的哈希,要求如果文本字符串相同,則哈希是相同的。 我決定使用Java的.hashValue(),因爲它非常簡單直接(並且我可以容忍潛在的碰撞) - 或者我認爲。
我的C#實現結果變得難以忍受。C#迭代非常緩慢的字符數組

這是在C#中實現(Java是幾乎相同):

 char[] val = string.ToCharArray(); 
     int hash = 0; 
     for (int i = 0; i < string.Count(); i++) { 
      hash = 31 * hash + val[i]; 
     } 

現在我通過在兩個文本字符串,無論是從文本文件在讀取光盤(C#,System.IO.File.ReadAllText) ,拳頭是10kb,第二個是100kb

java通過它們兩個拉動併產生結果。對於10kb的文件,C#需要大約600ms,然後後者需要50秒。在本質上,C#版本不會線性縮放,並且在一定的尺寸下,它變成不可行的方法。 鑑於指數縮放,並且我不能fanthom ADD和MUL開始需要更多時間,它使我相信它必須是一些內存管理與C#索引char數組混淆。 這是預期的行爲......還是我錯過了什麼? :-)

此致敬禮。

+2

您是否嘗試過使用'val.Length',因爲count方法實際上可能通過每次計算字符串? –

+3

「字符串」甚至是合法的變量名嗎? – Polyfun

+0

@ShellShock不,它不是。 – Servy

回答

7
for (int i = 0; i < string.Count(); i++) { 

在這一行,應該要麼使用string.Length(沒有括號),或者,優選地,val.Length

Count()是一種擴展方法,通過在每次調用它時枚舉該字符串來獲取字符串的長度。

的更常規的相同算法的C#實現將是:

int hash = 0; 
foreach(char c in string) 
{ 
    hash = 31 * hash + c; 
} 

如在評論中指出,string是不是有效的變量名是C#,因爲它是一個關鍵字(System.String別名) ,但爲了清楚起見,我在此保留。

+0

確實 - 使用Count()它變成了O(N^2)操作! –

+0

非常感謝,這就是:) ..考慮一下我的智慧。 「string」被替換爲我原來的問題,我認爲它是透明的。 – MrSmith

+0

我不會去,但在我看來,因爲我現在在這裏輸入...所以這裏去...如果字符串/字符串是不可變的。爲什麼.Count每次都必須「計數」長度?似乎不必要的低效率? – MrSmith