我不明白您为什么要在这里使用随机数生成器……但是,我可以帮助您加快速度。
布隆过滤器基本上是一个位向量,您可以在其中设置位。如果你想知道一个项目是否存在,如果项目可能存在,布隆过滤器会给你一个 true ,如果这个项目肯定不存在,它会给你一个false 。
(我在一个简单的文本编辑器中执行此操作,因此代码中可能存在一些错误)
我将假设您的哈希空间可以使用 32 位整数计算;如果您有一个非常大的布隆表,您可能希望使用 64 位整数。
因此,布隆过滤器最简单(可能也是最快)的实现是:
byte[] bloomFilter = new byte[MyBloomFilterSize];
foreach (var item in myItems)
{
int hash = Hash(item) & 0x7FFFFFFF;
int bit = 1 << (hash & 7); // you have 8 bits
int index = (hash >> 3) % MyBloomFilterSize;
bloomFilter[hash % MyBloomFilterSize] |= bit;
}
您可以尝试将 更改byte[]
为 auint[]
或 a ulong[]
; 我不确定这是否会有所不同。
如果你想检查一个项目是否存在,你计算相同的索引和位,并得到结果。
public bool PossiblyExists(MyItem item)
{
int hash = Hash(item) & 0x7FFFFFFF;
int bit = 1 << (hash & 7); // you have 8 bits
int index = (hash >> 3) % MyBloomFilterSize;
return (bloomFilter[hash % MyBloomFilterSize] & bit) != 0;
}
唯一剩下的就是计算哈希的速度。如果您使用的是整数,我会简单地将它与一个大素数相乘;如果您使用的是 SHA256 固定长度字节 [](您似乎正在这样做),则需要将其设为整数(或长整数)。
我在这里使用 Buffer.BlockCopy 的一个小技巧来转换类型。为了安全起见,我更喜欢使用数据中的几个字节,但由于 SHA256 应该已经是随机的,所以一个简单BitConverter.ToInt32(data, [0..28])
的也应该可以解决问题。
public int CalculateHash(byte[] data)
{
// Data = >128 bits = >16 bytes -- which is the same as >4 integers
int[] tmp = new int[4];
Buffer.BlockCopy(data, 0, tmp, 0, data.Length);
return tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
}
那应该这样做。