我的应用程序需要在数据集中每秒查找数百万次。 (HPC相关)
这是一个非常具体的用例,其中包含以下内容:
这种情况下最快的哈希函数是什么?
我至少知道一个:
hashValue = key % DATASET_FIXED_SIZE; // Java syntax for modulo
但我相信在我的情况下,该功能的分布是次优的。
所以 - 用上面的“知识” - 是最快的哈希函数。我是数学新手所以我不知道具体用例是否有minimal perfect hash function这样的东西。如果有,请告诉我。 : - )
注意:由于数据集的大小是固定的,我只关心查找性能。
编辑:我不太关心设置时间。我非常愿意为这个额外的小部分查找性能交换设置时间。这意味着哈希表方法甚至可能不是最好的方法,例如如果n小于10,则使用强力阵列扫描,如果10 <10,则使用二进制搜索。 n&lt; 50并使用一些哈希表方法是n> 50(n是对的数量,0和50只是我提出的一些数字,以明确这一点)更多信息:用例适用于内存数据结构。
答案 0 :(得分:0)
如果您打算使用Java HashMap,我能想到的最好的hashCode()实现如下:
public class Sample
{
private static int CLASS_ID = 0;
private final int id;
public Sample()
{
CLASS_ID++;
id = CLASS_ID;
}
// other constructors following the same pattern as in the default constructor
@Override
public int hashCode()
{
return id;
}
}
示例的所有构造函数都将确保CLASS_ID递增,然后分配给id字段。这个hashCode()函数将始终为每个实例返回一个唯一值,这可以避免将两个实例放在哈希映射中的一个桶中 - 假设哈希映射具有足够的桶。这会提高性能,但会以内存为代价。
此外,这个实现有两个弊端:
1:如果创建的实例多于整数的大小,则此实现将不起作用。但是,如果您打算仅使用200到300个实例,则情况不应该如此。
2:最伟大的&#39;虽然使用CLASS_ID作为(全局状态)静态变量。静态变量将在程序的整个运行时间内保留在内存中。
U,,,作为程序员,你需要投入某些实施的成本和权衡。
答案 1 :(得分:0)
Koloboke不使用Murmur;即使是线性散列,它也会使用更简单的混合:https://github.com/OpenHFT/Koloboke/blob/344089c9fc7c2b53ba7d1299eb29214206e1ab1d/lib/impl/src/main/javaTemplates/net/openhft/koloboke/collect/impl/hash/LHash.java#L34
在你的情况下,我建议为0-1000范围内的密钥(不是哈希)创建一个直接查找表,使用线性哈希表乘以一个随机常量的哈希值(你可以为每个特定的情况尝试几个看看哪些结果可以减少碰撞,或者只是坚持使用像-1640531527
这样的值。
int index = key * random & (rest_table_size_power_of_2 - 1);