Java哈希值:如何使它们有效可比?

时间:2012-06-14 12:15:05

标签: java hash comparison comparable

我有一对哈希值,比如

  
      
  1. 128ecf542a35ac5270a87dc740918404; d603ac0c04b9d08974482ae7fd4cf55
  2.   
  3. a1288b1c7e2257a90bad9bdfb7690fbb; f23828e312d90cb7fdadd6479236119c
  4.   
  5. ................................; .............. ..................
  6.   

我想让每一对与其他对比,意思是:

  

128ecf542a35ac5270a87dc740918404; d603ac0c04b9d08974482ae7fd4cf55d

保持原样;

的情况

  

d603ac0c04b9d08974482ae7fd4cf55d; 128ecf542a35ac5270a87dc74091840

4,它应该成为

  

128ecf542a35ac5270a87dc740918404; d603ac0c04b9d08974482ae7fd4cf55d

我的主要目标是有一个特定的函数,它比较一对的两个哈希值,并根据一些规则返回一个具有在其中排序的值的对。规则本身并不重要,唯一的要求是,它应该非常快,并且应该总是给出相同的结果,因为输入是(unique1,unique2)或(unique2,unique1)

THX!

一种显而易见但效率低下的方法是仅将每个哈希值中包含的数字相加并进行比较,并将哈希值与较小的和作为对中的第一个元素,将较大的和作为第二个元素。位置。

3 个答案:

答案 0 :(得分:5)

只需将两个字符串与通常的字符串比较(compareTo)进行比较,然后将较小的字符串放在第一位。这将保证您想要的。我希望这是非常便宜的,因为实际上哈希值在前几个字符中已经有所不同,然后比较不需要查看其余的字符串。此外,访问和比较非常少的字节数(如在您的示例中)是如此便宜,以至于只有当您比程序执行的其他操作更频繁地执行此操作时,您才能看到性能影响。

如果你没有将值作为字符串,而是作为字节数组或类似的东西,只需要自己实现一个简单的词典比较。

答案 1 :(得分:1)

编辑:我刚刚再次阅读了您的问题和主要目标。 我的答案是比较两对

如果你想在一对中对这两个哈希值进行排序,那么就应该线性地比较两个哈希值,并且在第一个不匹配的字符中首先将较低的值放在一起。可能很大,值已经在前几个字节上有所不同。


我认为你不能用Java做它,但你可以在C / ASM中为它创建一个函数,然后从Java到JNI使用它。

让我们看看:这些是32字节哈希值对。你知道这些对在';'处分开的位置字节32。

将您的耦合哈希值设为hahsA := (hA1;hA2)hashB := (hB1;hB2)

你选择第一对:

1)将0-15和33-49字节送到两个SSE寄存器并对其进行异或

hashA[0-15] := ( hashA1[0-15] XOR hashA2[0-15] ).

2)得到16-31和50-65字节的SSE寄存器和XOR它

hashA[16-31] := ( hashA1[16-31] XOR hashA2[16-31] ).

现在你有两个SSE寄存器填充了你夫妻的第一个和第二个16字节的XOR:

XMM0: hashA[0-15]
XMM1: hashA[16-31]

你拿第二对并做同样的事情。你有8个SSE寄存器,所以你可能不需要在2)之后从寄存器中取出值。

现在你有:

XMM0: hA[0-15]
XMM1: hA[16-31]
XMM2: hB[0-15]
XMM3: hB[16-31]


if( XMM0 == XMM2 AND XMM1 == XMM3 ) then hA and hB are equal.

当然,如果你的哈希码大于32字节,你需要做进一步的步骤,但假设你的哈希码长度都相同,这个算法需要:

1)加载两个16字节和xor = 3指令 2)3条指令

1)和2)再次为第二对:6条指令 最后2个比较指令和1个AND指令

总结了每个比较夫妻的15个指令,而不是测量函数调用。我不能说它是O(1)因为如果哈希值更大,指令的数量也在增长。

如果效率真的很重要,这是一种方法。但无论如何,我认为你不能比O(n)做得少,因为你必须比较所有的角色。

答案 2 :(得分:0)

很容易优化两个字符串不相等的情况,String.equals(Object)的实现已经这样做了。

但是,两个字符串相等但不是==的情况本身就是O(N)

现在可以在某些情况下改进:

  • 您可以向对象添加额外的私有字段,
  • 对象的状态必须相对于equals运算符和
  • 稳定
  • 需要反复比较同一组对象实例。

在这些先决条件下,有一种趋向于O(1)的算法。但是,您不能将它应用于表示为String值的哈希值,因为第一个和(可能)第三个条件不成立。