Python MD5 哈希快速计算
我会尽量详细地解释我的问题和我想到的解决办法。
我使用了这段代码:
for root, dirs, files in os.walk(downloaddir):
for infile in files:
f = open(os.path.join(root,infile),'rb')
filehash = hashlib.md5()
while True:
data = f.read(10240)
if len(data) == 0:
break
filehash.update(data)
print "FILENAME: " , infile
print "FILE HASH: " , filehash.hexdigest()
然后我用 start = time.time() 和 elapsed = time.time() - start 来测量计算一个哈希值需要多长时间。当我把代码指向一个大小为653MB的文件时,结果是:
root@Mars:/home/tiago# python algorithm-timer.py
FILENAME: freebsd.iso
FILE HASH: ace0afedfa7c6e0ad12c77b6652b02ab
12.624
root@Mars:/home/tiago# python algorithm-timer.py
FILENAME: freebsd.iso
FILE HASH: ace0afedfa7c6e0ad12c77b6652b02ab
12.373
root@Mars:/home/tiago# python algorithm-timer.py
FILENAME: freebsd.iso
FILE HASH: ace0afedfa7c6e0ad12c77b6652b02ab
12.540
好的,现在在处理一个653MB的文件时大约需要12秒。我的问题是,我打算在一个程序中使用这段代码,这个程序会处理多个文件,其中一些可能有4GB、5GB或6GB,这样计算的时间会更长。我在想有没有更快的方法来计算文件的哈希值?也许可以使用多线程?我用另一个脚本每秒检查一次CPU的使用情况,发现我的代码只在使用2个CPU中的1个,而且最多只使用了25%。有没有办法可以改变这种情况?
谢谢大家提前提供的帮助。
4 个回答
就我个人的经验来说,执行这个操作:
c:\python\Python.exe c:\python\Tools\scripts\md5sum.py cd.iso
在我的笔记本电脑上花了9.671秒(我的电脑是2GHz的双核处理器,配有80GB的SATA硬盘)。
正如其他人提到的,MD5的计算主要受硬盘速度的影响,不过你提到的12秒的测试结果可能已经接近最快的速度了。
另外,Python的md5sum.py使用的缓冲区大小是8096(虽然我相信他们其实是想用4096或8192)。
我发现增加缓冲区的大小对我有帮助,但也有个限度。我一开始设置为1024,然后每次都把它乘以2的N次方,从N=1开始逐渐增加。通过这种方法,我发现我的系统上,缓冲区大小设置为65536似乎是最好的选择。不过,这样做只让我运行时间提高了大约7%。
分析显示,大约80%的时间都花在了MD5更新方法上,剩下的20%则是在读取文件。由于MD5是一种串行算法,而Python中的算法已经用C语言实现了,我觉得在加速MD5部分上能做的事情不多。你可以尝试同时计算两个不同文件的MD5值,但正如大家所说的,最终你还是会受到磁盘访问速度的限制。
在你的情况下,哈希计算几乎肯定会受到输入输出速度的限制(除非你在一台处理器非常慢的机器上运行)。所以,使用多线程或者同时处理多个文件,可能不会给你带来预期的效果。
把文件分散到多个硬盘上,或者放在更快的硬盘(比如固态硬盘SSD)上,可能会有所帮助,尽管这可能不是你想要的解决方案。