代码之家  ›  专栏  ›  技术社区  ›  Andrey Adamovich

混合数字和文字标识符的最佳哈希函数

  •  6
  • Andrey Adamovich  · 技术社区  · 16 年前

    出于性能方面的考虑,我需要将一组由字符串标识的对象分成组。对象可以由数字或以前缀(限定)形式的字符串标识,用点分隔标识符的各个部分:

    12
    323
    12343
    2345233
    123123131
    ns1:my.label.one
    ns1:my.label.two
    ns1:my.label.three
    ns1:system.text.one
    ns2:edit.box.grey
    ns2:edit.box.black
    ns2:edit.box.mixed
    

    数字标识符从1到数百万。文本标识符最有可能有许多以相同的名称空间前缀(ns1:)和相同的路径前缀(edit.box.)开头。

    为此,最好的哈希函数是什么?如果我能根据对象标识符统计信息以某种方式预测bucket的大小,那就太好了。有没有一些好的文章可以根据一些统计信息构造好的哈希函数?

    这样的标识符有数百万个,但目的是根据散列函数将它们分成1-2千个组。

    3 回复  |  直到 16 年前
        1
  •  3
  •   Steve Jessop    16 年前

    两个好的散列函数都可以映射到相同的值空间中,并且通常不会由于组合它们而导致任何新的问题。

    所以散列函数可以如下所示:

    if it's an integer value:
        return int_hash(integer value)
    return string_hash(string value)
    

    除非你的整数在某些值周围有任何聚集,模n,其中n是可能的桶数,那么 int_hash 只能返回其输入。

    选择字符串散列不是一个新问题。尝试“DJB2” http://www.cse.yorku.ca/~oz/hash.html )或者类似的,除非你有淫秽的表演要求。

    我不认为修改hash函数来考虑常见的前缀有多大意义。如果您的散列函数是一个很好的开头,那么一般的前缀不太可能创建任何散列值的聚集。

    如果您这样做,并且散列不会意外地表现糟糕,并且您将数百万散列值放入几千个bucket中,那么bucket总体将正常分布,平均值(几百万/几千)和方差1/12(几千)^2

    平均每个桶有1500个条目,这使得标准偏差在430左右。正态分布的95%在平均值的2个标准差内,所以95%的桶将包含640-2360个条目,除非我做了错误的计算。这足够吗,或者你需要更接近相似大小的水桶吗?

        2
  •  0
  •   Fragsworth    16 年前

    你跟我一起去很安全 sha1 截短到你想要的大小。

    它不会非常有效,但哈希函数可能不会成为瓶颈?

        3
  •  0
  •   KernelJ    16 年前

    我认为在这些字符串上使用CRC16是一个合理的散列值,组的大小不能超过1-2000。

    这应该使哈希表大约为1MB+不管您在其中有多少项*4字节,所以我们说的是50MB,然后您还可以存储所有实际数据,最好是非常小的。