2013-07-18 84 views
3

這是在參考Get MD5 hash of big files in PythonHashlib in Windows and LinuxHashlib:在md5.update使用組塊的最佳大小()

在響應於這兩個問題,建議在函數MD5使用較大的數據塊.update()來提高性能。

我所做的所有測試似乎表明使用較小的塊可以獲得最佳性能。

考慮下面的代碼:

def test(factor): 
    filehash = hashlib.md5() 
    blk_size_to_read = filehash.block_size * (2**factor) 
    with open(largetestfile, 'rb') as f: 
     read_data = f.read(blk_size_to_read) 
     filehash.update(read_data) 
    filehash.digest() 

if __name__ == '__main__': 
    for ctr in xrange(0, 12): 
     funcstr = "test({})".format(str(ctr)) 
     timetaken = timeit.timeit(funcstr, setup="from __main__ import test", number = 5000) 
     print "Factor: {} Time: {}".format(str(ctr), str(timetaken)) 

我已經做了所有的測試表明,最佳性能是使用factor 0或1時(即,64或128個字節)來實現的。

爲什麼我看到與引用問題中指出的結果不同的任何原因?

我試圖二進制和純文本文件有大小不等的700MB到1.2GB,並使用Python 2.7.3我在Ubuntu 12.04

次要的問題:我使用timeit的方式,它應該是什麼?

回答

3

發現錯誤!我只有一塊,然後什麼都不做!

改變

with open(largetestfile, 'rb') as f: 
    read_data = f.read(blk_size_to_read) 
    filehash.update(read_data) 

with open(testfile, 'rb') as f: 
    while (True): 
     read_data = f.read(blk_size_to_read) 
     if not read_data: 
      break 
     filehash.update(read_data) 

來解決該問題。

UPDATE:

我跑上面的程序,建立緩衝區的最佳大小的稍作修改的版本逐步更新使用()來查找特定文件的散列時使用。我還想確定增量散列是否有任何好處,而不是一次性計算文件的散列(除了內存約束)。

我爲此創建了20個文件(包含隨機數據),文件大小從4096字節到2.1 GB。這些文件中的每一個的md5散列計算使用從2**6字節(64字節 - 塊大小)開始直到2**20字節的緩衝區大小。使用timeit每個都運行100次,記錄執行時間最短的執行時間。還記錄了整個文件一次散列計算的執行時間。

的結果如下...

FileName   Filesize  Chunksize  Chunked Time Complete Time  %diff 
file5.txt     4096   4096  0.0014789  0.0014701   -0.60% 
file6.txt     8192   524288  0.0021310  0.0021060   -1.19% 
file7.txt    16384   16384  0.0033200  0.0033162   -0.12% 
file8.txt    32768   65536  0.0061381  0.0057440   -6.86% 
file9.txt    65536   65536  0.0106990  0.0112500   4.90% 
file10.txt    131072   131072  0.0203800  0.0206621   1.37% 
file11.txt    262144   524288  0.0396681  0.0401120   1.11% 
file12.txt    524288  1048576  0.0780780  0.0787551   0.86% 
file13.txt    1048576  1048576  0.1552539  0.1564729   0.78% 
file14.txt    2097152   262144  0.3101590  0.3167789   2.09% 
file15.txt    4194304   65536  0.6295781  0.6477270   2.80% 
file16.txt    8388608   524288  1.2633710  1.3030031   3.04% 
file17.txt   16777216   524288  2.5265670  2.5925691   2.55% 
file18.txt   33554432   65536  5.0558681  5.8452392   13.50% 
file19.txt   67108864   65536  10.1133211  11.6993010   13.56% 
file20.txt   134217728   524288  20.2226040  23.3923230   13.55% 
file21.txt   268435456   65536  40.4060180  46.6972852   13.47% 
file22.txt   536870912   65536  80.9403431  93.4165111   13.36% 
file23.txt   1073741824   524288 161.8108051 187.1303582   13.53% 
file24.txt   2147483648   65536 323.4812710 374.3899529   13.60% 

Chunked Time是當文件被分成卡盤和增量hased執行時間; Complete Time是整個文件一次散列時的執行時間。 %diff是分塊時間和「完成時間」之間的百分比差異。

觀察:

  1. 對於更小的文件塊的大小几乎總是等於文件大小和似乎是在採用這兩種方法沒有什麼優勢。
  2. 對於較大的文件(33554432(2**25)字節及以上),使用增量方法似乎有相當大的性能優勢(較短時間),而不是一次性散列整個文件。
  3. 對於大文件它最好塊/緩衝器大小爲65536(2**16)字節

注:蟒2.7.3; Ubuntu 12.06 64位; 8 Gig的RAM 用於此的代碼在這裏可用... http://pastebin.com/VxH7bL2X

+0

爲了好奇的緣故,你能告訴我們你發現什麼是最佳的塊大小嗎? – 2rs2ts

+0

當您的塊大小增加時,性能將趨於朝着系統運行md5代碼的最大理論吞吐量逐漸增加。當你緩衝1MiB時,速度的增加早已變得無關緊要。如果你想選擇一個任意的緩衝區大小,我建議128k。所有哈希函數都是如此。 – gps

+1

@ 2rs2ts最佳大小爲65536字節。請參閱上面的更新。 – Verma