我正在计算Java和C#中的文本字符串的散列,要求是如果文本字符串相同,则散列是相同的。 我决定使用Java的.hashValue(),因为它非常简单直接(并且我对潜在的碰撞有容错性), - 或者我认为。左右。 我的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#版本不能线性扩展,并且在一定的大小下它变成不可行的方法。 鉴于指数缩放,并且我不能幻想ADD和MUL开始花费更多时间,它让我相信它必须是一些内存管理因C#索引char数组而变得混乱。 这是预期的行为......还是我错过了什么? : - )
最好的问候。
答案 0 :(得分: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
的别名),但为了清楚起见,我将其保留在这里。