Python MD5哈希更快的计算方法

3
我会尽力解释我的问题和我解决问题的思路。
我使用以下代码:
    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 来计算哈希的时间。当我将代码指向一个大小为 653 兆字节的文件时,得到的结果如下:

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秒左右的时间。我的问题是我打算在一个程序中使用这段代码来处理多个文件,其中一些文件可能达到4/5/6GB大小,这将需要更长的计算时间。我想知道是否有更快的方法来计算文件的哈希值?也许可以通过多线程来实现?我使用另一个脚本来检查CPU的使用情况,发现我的代码只使用了我的2个CPU中的1个,最大值只有25%,有没有办法改变这种情况?

提前感谢大家的帮助。


1
尝试对您的代码进行分析,看看大部分时间是在read()方法还是update()方法中花费。多进程只能帮助update()方法。在尝试多进程之前,请查看是否使用psyco可以提供所需的速度。 - Justin Peel
4个回答

4
在您的情况下,哈希计算几乎肯定会受到I/O限制(除非您在一台处理器非常慢的机器上运行它),因此多线程或同时处理多个文件可能不会产生预期的结果。将文件分配到多个驱动器上或放在更快(SSD)的驱动器上可能会有所帮助,尽管这可能不是您正在寻找的解决方案。

1
就代码优化而言,是否有比通常的循环“file.read(bytes)”操作更有效的基于代码的方法来计算大文件的MD5哈希值?为了背景,我正在处理一个能够处理约30 GB /秒的工业系统。(是的,我知道这个线程已经过时了) - andrewgu

2
这里磁盘操作不是瓶颈吗? 假设读取速度为80MB /秒(这是我的硬盘的表现),需要大约8秒钟才能读取文件。

2

就这个问题而言,做如下操作:

c:\python\Python.exe c:\python\Tools\scripts\md5sum.py cd.iso

在我的笔记本电脑上(2GHz Core2 Duo和80 GB SATA笔记本硬盘),需要9.671秒。

正如其他人提到的,MD5是磁盘密集型操作,但你的12秒基准测试可能已经接近最快速度了。

此外,Python的md5sum.py使用8096作为缓冲区大小(尽管我确定他们的意思是4096或8192)。


2
它帮助我增加了缓冲区大小,但只有到一定程度。我从1024开始,每次乘以2 ^ N,从1开始递增。通过这种方法,我发现在我的系统上,缓冲区大小为65536似乎是最好的选择。然而,这只让我在运行时间上获得了约7%的改善。
分析表明,大约80%的时间花在MD5更新方法上,另外20%用于读取文件。由于MD5是串行算法,并且Python算法已经在C中实现,因此我认为您无法做太多来加速MD5部分。您可以尝试并行计算两个不同文件的MD5值,但正如其他人所说,您最终将受到磁盘访问速度的限制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接