Максимальный предел байтов в обновлении метода модуля Hashlib Python

Я пытаюсь вычислить хэш md5 файла с помощью функции hashlib.md5() из модуля hashlib.

Так что я написал этот кусок кода:

Buffer = 128
f = open("c:\\file.tct", "rb")
m = hashlib.md5()

while True:
   p = f.read(Buffer)
   if len(p) != 0:
      m.update(p)
   else:
      break
print m.hexdigest()
f.close()

Я заметил, что обновление функции происходит быстрее, если я увеличиваю значение переменной Buffer на 64, 128, 256 и т. д. Есть верхний предел, который я не могу превысить? Я предполагаю, что это может быть только проблема с оперативной памятью, но я не знаю.


person maxim    schedule 09.02.2011    source источник


Ответы (3)


Большие (≈2**40) размеры блоков приводят к MemoryError, т. е. нет никаких ограничений, кроме доступной оперативной памяти. С другой стороны, bufsize на моей машине ограничено 2**31-1:

import hashlib
from functools import partial

def md5(filename, chunksize=2**15, bufsize=-1):
    m = hashlib.md5()
    with open(filename, 'rb', bufsize) as f:
        for chunk in iter(partial(f.read, chunksize), b''):
            m.update(chunk)
    return m

Большой chunksize может быть таким же медленным, как и очень маленький. Измерьте это.

Я обнаружил, что для файлов размером ≈10MB 2**15 chunksize является самым быстрым для файлов, которые я тестировал.

person jfs    schedule 11.02.2011
comment
Я только что попробовал это в 3.1.3, и мне нужно было явно сравнить пустую строку байтов с iter(partial(f.read, chunksize, b''), как теперь выглядит ''!=b''. - person pix; 16.10.2014

Чтобы иметь возможность обрабатывать произвольно большие файлы, вам нужно читать их блоками. Размер таких блоков предпочтительно должен быть степенью 2, а в случае md5 минимально возможный блок состоит из 64 байтов (512 бит), поскольку 512-битные блоки являются единицами, с которыми работает алгоритм.

Но если мы пойдем дальше и попытаемся установить точный критерий того, является ли, скажем, 2048-байтовый блок лучше, чем 4096-байтовый блок... мы, скорее всего, потерпим неудачу. Это нужно очень тщательно проверять и измерять, и почти всегда значение выбирается произвольно, исходя из опыта.

person ulidtko    schedule 09.02.2011

Значение буфера — это количество байтов, которые одновременно считываются и сохраняются в памяти, так что да, единственным ограничением является ваша доступная память.

Однако большие значения не являются автоматически более быстрыми. В какой-то момент вы можете столкнуться с проблемами подкачки памяти или другими замедлениями при выделении памяти, если буфер слишком велик. Вы должны экспериментировать со все большими и большими значениями, пока не достигнете убывающей отдачи в скорости.

person shang    schedule 09.02.2011