Python MD5哈希更快的计算

时间:2010-05-11 19:00:25

标签: python multithreading md5 multicore

我会尽力解释我的问题以及我对如何解决问题的想法。

我使用此代码

    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我测量计算哈希所需的时间。将我的代码指向具有653megs的文件,结果是:

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

好了现在12秒+ - 在一个653mb的文件上,我的问题是我打算在一个程序上使用这个代码,这个程序将运行多个文件,其中一些可能是4/5 / 6Gb而且需要更长时间才能使用计算。我想知道是否有更快的方法来计算文件的哈希值?也许通过做一些多线程?我使用另一个脚本来逐步检查CPU的使用情况,我发现我的代码只使用了2个CPU中的1个而且只有25%的最大值,我可以用任何方式更改它吗?

提前感谢大家提供帮助。

4 个答案:

答案 0 :(得分:4)

在你的情况下哈希计算几乎肯定会受到I / O限制(除非你在一台处理器真的很慢的机器上运行它),所以多线程或一次处理多个文件可能不会产生你预期的结果

在多个驱动器或更快的(SSD)驱动器上拦截文件可能会有所帮助,即使这可能不是您正在寻找的解决方案。

答案 1 :(得分:2)

磁盘操作不是这里的瓶颈吗? 假设80MB /秒的读取速度(这是我的硬盘执行的方式),读取文件大约需要8秒。

答案 2 :(得分:2)

为了它的价值,这样做:

c:\python\Python.exe c:\python\Tools\scripts\md5sum.py cd.iso
我的笔记本电脑需要9.671秒(带有80 GB SATA笔记本电脑硬盘的2GHz core2 duo)。

正如其他人所提到的,MD5受磁盘限制,但你的12秒基准测试可能非常接近你能获得的速度。

另外,python的md5sum.py使用8096作为缓冲区大小(即使我确定它们意味着4096或8192)。

答案 3 :(得分:1)

它帮助我增加了缓冲区大小,达到了一定程度。我从1024开始并将其乘以2 ^ N,每次从1开始增加N。使用这种方法,我发现在我的系统上,缓冲区大小65536似乎和它一样好。但是,它只给了我大约7%的运行时间改善。

分析表明大约80%的时间花在MD5更新方法上,另外20%的时间是在文件中读取。由于MD5是一个串行算法,并且Python算法已经在C中实现,我认为你可以做很多事情来加速MD5部分。您可以尝试并行计算两个不同文件的MD5,但正如大家所说,您最终将受到磁盘访问速度的限制。