2013-07-18 10 views
3
이이 함수 MD5 데이터의 더 큰 청크를 사용하도록 권장되고, 이러한 두 질문에 대한 응답에 Get MD5 hash of big files in PythonHashlib in Windows and Linux

Hashlib : 청크의 최적 크기 md5.update에 사용하는()

참조에

.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 바이트) 달성을 나타냅니다.

인용 된 질문에 표시된 결과와 다른 결과가 나타나는 이유는 무엇입니까?

나는 7백메가바이트에서 1.2GB에 이르기까지 다양한 크기의 바이너리 및 일반 텍스트 파일을 시도하고 우분투 12.04에 파이썬 2.7.3 사용하고

차 질문 : 나는 그것이 있어야하는 방법을 timeit 사용하고?

답변

3

오류를 발견했습니다! 나는 read 한 덩어리 만 보내고 아무 것도하지 않았습니다!

는 문제를 해결하기 위해

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) 

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

변경.

UPDATE :

내가 점진적으로 지정된 파일의 해시를 찾기 위해 업데이 트를()를 사용할 때 사용되는 버퍼의 최적 크기를 설정하기 위의 프로그램의 약간 수정 된 버전을 달렸다. 또한 파일의 해시를 메모리 제약 조건을 제외하고 계산하는 것보다 점진적 해싱에서 이점이 있는지 여부를 확인하고자했습니다.

4096 바이트부터 최대 2.1GB의 파일 크기로 20 개의 파일 (무작위 데이터 포함)을 생성했습니다. 각 파일에 대한 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; 우분투 12.06 64 비트; 8 기가 RAM 여기에 사용 된 코드는 여기에서 볼 수 있습니다. ... http://pastebin.com/VxH7bL2X

+0

호기심 때문에 최적의 청크 크기를 찾았습니까? – 2rs2ts

+0

청크 크기가 커질수록 성능은 md5 코드를 실행하는 시스템의 이론적 인 최대 속도를 향하여 점차 증가합니다. 당신이 1MiB를 버퍼링 할 무렵에는 속도의 증가가 오래 전부터 부적절 해졌습니다. 임의의 버퍼 크기를 선택하려면 128k를 제안하십시오. 이것은 모든 해시 함수에 해당됩니다. – gps

+1

@ 2rs2ts 최적의 크기는 65536 바이트입니다. 위의 내 대답에 대한 업데이트를 참조하십시오. – Verma