我需要比较大块数据的相等性,我需要每秒比较很多,快速。每个对象都保证大小相同,并且可能/可能只是略有不同(在未知位置)。
我已经看到,从下面的交互式会话中,如果差异在字符串的末尾,则使用==
运算符的字节字符串可能会更慢,如果在字符串末尾附近存在差异,则可能会非常快开始。
我认为可能有某种方法可以使用某种哈希来加快速度,当然计算md5哈希值并且比较速度慢,但是python的内置哈希确实显着加快了速度。
但是,我不知道这个哈希的实现细节,它是否真的像哈希一样,我觉得hash(a) == hash(b)
然后a == b
非常可能?如果哈希冲突相当罕见,我很高兴有一些不正确的结果(在需要an array of 200 PS3s several hours to make a collision的意义上很少见)
In [1]: import hashlib
In [2]: with open('/dev/urandom') as f:
...: spam = f.read(2**20 - 1)
...:
In [3]: spamA = spam + 'A'
In [4]: Aspam = 'A' + spam
In [5]: spamB = spam + 'B'
In [6]: timeit spamA == spamB
1000 loops, best of 3: 1.59 ms per loop
In [7]: timeit spamA == Aspam
10000000 loops, best of 3: 66.4 ns per loop
In [8]: timeit hashlib.md5(spamA) == hashlib.md5(spamB)
100 loops, best of 3: 4.42 ms per loop
In [9]: timeit hashlib.md5(spamA) == hashlib.md5(Aspam)
100 loops, best of 3: 4.39 ms per loop
In [10]: timeit hash(spamA) == hash(spamB)
10000000 loops, best of 3: 157 ns per loop
In [11]: timeit hash(spamA) == hash(Aspam)
10000000 loops, best of 3: 160 ns per loop
答案 0 :(得分:28)
Python的哈希函数是为速度而设计的,并映射到64位空间。由于birthday paradox,这意味着您可能会在大约50亿个条目中发生冲突(可能更早,因为散列函数不是加密的)。此外,hash
的精确定义取决于Python实现,可能是体系结构甚至是机器特定的。不要在多台机器上使用它,你想要相同的结果。
md5被设计为加密哈希函数;即使输入中的轻微扰动也会完全改变输出。它还映射到一个128位的空间,这使得你根本不可能遇到任何碰撞,除非你专门寻找一个。
如果你可以处理冲突(即测试存储桶中所有成员之间的相等性,可能使用像MD5或SHA2这样的加密算法),Python的哈希函数就可以了。
还有一件事:为了节省空间,如果将数据写入磁盘,则应以二进制形式存储数据。 (即struct.pack('!q', hash('abc'))
/ hashlib.md5('abc').digest()
)。
作为旁注:is
不等同于Python中的==
。你的意思是==
。