Ruby:帮助改进哈希算法

时间:2018-07-31 19:42:54

标签: ruby performance hash blockchain

在红宝石语言方面,我还是一个相对较新的人,但是我知道该语言内置了许多便利方法。我试图生成一个“哈希”以在低级区块链验证程序中进行检查,并且我想知道是否有任何“便利方法”可以让您尝试使这种哈希算法更有效。我想我可以通过利用ruby的最大整数大小来提高效率,但是我不确定。

下面是当前代码,该代码接受要散列的字符串,将其解压缩为UTF-8值数组,对这些值中的每一个进行计算密集型数学运算,并在完成数学运算后将所有这些值求和它们,以65,536为模取该值,然后返回该值的十六进制表示。

def generate_hash(string)
  unpacked_string = string.unpack('U*')
  sum = 0
  unpacked_string.each do |x|
    sum += (x**2000) * ((x + 2)**21) - ((x + 5)**3)
  end
  new_val = sum % 65_536 # Gives a number from 0 to 65,535
  new_val.to_s(16)
end    

在非常大的区块链上,有一个非常大的性能问题,我正在设法解决。任何帮助都会很棒!

1 个答案:

答案 0 :(得分:3)

首先,最不可能创建比仅使用String#hash更有效的方法。这是您尝试构建更好的捕鼠器的情况。

老实说,您的哈希算法效率很低。散列的全部要点是一种快速,低开销的方法,可以快速获取一个“唯一”(尽可能唯一)的整数来表示任何对象,从而避免按值进行比较。

以此为前提,如果您开始在散列算法中进行任何类型的密集计算,那将适得其反。一旦开始实现modulopow函数,效率就会降低。

通常,最佳做法是获取可以表示为整数的对象的值,并对它们执行位运算,通常使用质数来帮助减少哈希冲突。

def hash
  h = value1 ^ 393
  h += value2 ^ 17
  h
end

在您的示例中,由于某种原因,您将哈希值强制为16位无符号整数的最大值(通常使用32位),尽管如果在Ruby端进行比较,则为31 -位,因为Ruby如何屏蔽Fixnum值。 Fixnum在Ruby方面已被弃用,但是在内部BignumFixnum的处理方式之间存在相同的阈值。 Integer类仅在Ruby一侧提供了一个接口,因为这两个接口确实不应该在C代码之外公开。

在您使用字符串的特定示例中,我只是将它们符号化。这保证了一种快速有效的方法来确定两个字符串是否相等而几乎没有开销,并且比较2个符号与比较2个整数完全相同。如果要比较大量的字符串,则需要对此方法进行警告。创建符号后,该符号在程序的生命周期内仍然有效。等于它的所有其他字符串都将返回相同的符号,但是只要程序运行,就不能删除该符号的内存(仅几个字节)。如果使用这种方法比较成千上万的唯一字符串,那就不好了。