[英]Fastest way to search in sorted static array
我正在寻找一种最快的方式来搜索一个排序,固定的32位密钥数组。 数组大小和数据是静态的,永远不会改变。 该数组的大小约为1000-10000个唯一元素。 搜索范围明显更广(~100000),因此无法找到大量搜索值。 我只对完全匹配感兴趣。
以下是搜索的进度:
密钥的一个潜在有趣的特性是,即使它们在整数值方面不是很接近,它们中的大多数也只与它们最近的邻居有几个不同的位(~1-4)。
我发现大多数答案都指向二进制搜索,但没有一个涉及静态数组的情况,这可能会开辟一些优化可能性。
我完全控制数据结构,现在它是一个固定的,排序的数组,但如果它不是最佳的我可以改变它。 我还可以添加预先计算的信息,因为如果不占用不合理的内存量,数据不会改变。
目标是在CPU和内存方面都很高效,尽管CPU是这里的优先事项。
使用C ++虽然这可能不会对答案产生太大影响。
考虑到您的静态数组永远不会改变,并且您拥有无限的预处理能力,我认为最好的方法是为每个数组创建一个特定的哈希函数。
我的方法 - 定义参数化哈希函数(java中的代码):
private static Function<Long, Integer> createHashFunction(int sz) {
int mvLeft = ThreadLocalRandom.current().nextInt(30);
int mvRight = ThreadLocalRandom.current().nextInt(16);
int mvLeft2 = ThreadLocalRandom.current().nextInt(10);
int mvRight2 = ThreadLocalRandom.current().nextInt(16);
int mvLeft3 = ThreadLocalRandom.current().nextInt(16);
int mvRight3 = ThreadLocalRandom.current().nextInt(20);
return (key) -> {
// These operations are totally random, and has no mathematical background beneath them!
key = ~key + (key << mvLeft);
key = key ^ (key >>> mvRight);
key = key + (key << mvLeft2);
key = key ^ (key >>> mvRight2);
key = key + (key << mvLeft3);
key = key ^ (key >>> mvRight3);
return (int) (Math.abs(key) % sz); // sz is the size of target array
};
}
对于每个测试阵列,找到这样的参数组合,即最大桶大小是最小的。
一些测试(输入数组的大小为10k,填充了随机元素):
考虑到最大桶大小为2,可以将两个值映射到一个64位整数,这种方法只会导致一次内存跳转,而最简单的CPU操作 - 散列是通过xor,plus和shift进行的,应该是非常快和比特比较。
但是,您的数据可能不是那么好,并且可能需要3的铲斗大小,这会破坏铲斗物品long long
使用的可能性。 在这种情况下,您可以尝试找到一些不错的哈希函数,而不是我写的随机混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.