在Javascript中实现Zobrist哈希

时间:2014-07-17 21:03:54

标签: javascript performance hashtable v8

我需要在Javascript中为一个国际象棋引擎实现Zobrist哈希,我想知道实现这个目标的最佳方法是什么。现在,我不是一个计算机科学家,从来没有正式的算法和数据结构类,所以如果我对此有点不满,我很抱歉......

根据我的理解,我需要一个64位散列函数来编码一个低于该位置的位置,从而产生太多的碰撞。现在在javascript中我只能访问32位数字。还有一个问题是我如何实现哈希表以及如何通过节点中的V8引擎“幕后”实现它。

我可以将它作为长度为TABLESIZE的javascript数组,并执行以下操作:

var table = new Array();

table[hashCodeLo % TABLESIZE] = {
    hashCodeLo: hashCodeLo,
    hashCodeHi: hashCodeHi,
    someProperty: someValue
};

其中hashCodeLo和hashCodeHi表示代码的高32位和低32位,并且TABLESIZE< 2 ^ 32。我存储这些以检测来自%TABLESIZE位的冲突。现在我猜测,因为TABLESIZE很大而且我分配非连续的元素V8会把它踢进“字典模式”,所以我不妨打扰它成为一个由TABLESIZE整数索引的数组,而是做类似的事情:

var table = {};

table[hashCode] = {
    someProperty: someValue
}

这里hashCode只是我64位hashCode的字符串表示。由于我不确定“词典模式”如何在幕后工作,我不确定哪个更好。此外,我不知道我是否通过使用像'1983981918391'这样的密钥来使用更多的内存,而不是像以下那样更紧凑的表示:

hashCode = String.fromCharCode(FIRST_16BITS, SECOND_16BITS, THIRD_16BITS, FOURTH_16BITS)

我甚至不确定这是否按照我打算的方式运作......

由于这是引擎的一个关键部分,我想尽可能地挤出这个性能,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:2)

  

根据我的理解,我需要一个64位散列函数来编码一个低于该位置的位置,从而产生太多的碰撞。

至少不是transposition table - 它的大小几乎不是2 64

如果你正在实现这个来对位置本身进行编码(并通过比较64位散列来检测一些冲突),那么是的,你可以使用64位,如果这是文献推荐的那样(尽管你可能想要尝试52位)。

  

现在在javascript中我只能访问32位数字。

没有。 JavaScript中的数字是64位浮点数,您可以精确地存储多达52位的整数。只有按位运算符限制为32位整数(如果需要,将向其转换数字)。

然而,阵列本身的长度限制为2 32 ;但即使这应该绰绰有余。

  

还有一个问题是我如何实现哈希表及其实现方式"在幕后"通过节点中的V8引擎。

只需实现就像一个数组。尝试用null值填充它以进行初始化,并查看非稀疏数组是否表现更好。如果您关心效果,测试

  

hashCodeLo和hashCodeHi表示代码的高32位和低32位,并且TABLESIZE< 2 ^ 32。我存储这些来检测碰撞

我使用Uint32Array而不是对象数组。根据{{​​1}}和someProperty的不同,您可能只想在正常数组或标量本身(可能使用DataView)中存储对象的索引。代码可能如下所示:

someValue