Какой самый эффективный способ чтения больших двоичных файлов Python
У меня есть большой (21 ГБ) файл, который я хочу прочитать в память и затем передать подпрограмме, которая прозрачно обрабатывает данные для меня. Я на Python 2.6.6 на Centos 6.5, поэтому обновление операционной системы или Python не вариант. В настоящее время я использую
f = open(image_filename, "rb")
image_file_contents=f.read()
f.close()
transparent_subroutine ( image_file_contents )
что медленно (~15 минут). Прежде чем я начну читать файл, я знаю его размер, потому что я вызываю os.stat( image_filename).st_size
так что я мог бы заранее выделить немного памяти, если это имело смысл.
Спасибо
3 ответа
С помощью генератора
def generator(file_location):
with open(file_location, 'rb') as entry:
for chunk in iter(lambda: entry.read(1024 * 8), b''):
yield chunk
go_to_streaming = generator(file_location)
Следуя предложению Дитриха, я измеряю эту технику mmap на 20% быстрее, чем одно большое чтение для входного файла объемом 1,7 ГБ.
from zlib import adler32 as compute_cc
n_chunk = 1024**2
crc = 0
with open( fn ) as f:
mm = mmap.mmap( f.fileno(), 0, prot = mmap.PROT_READ, flags = mmap.MAP_PRIVATE )
while True:
buf = mm.read( n_chunk )
if not buf: break
crc = compute_crc( buf, crc )
return crc
Я знаю, что задал этот вопрос 9 лет назад, однако, просматривая его, у меня появилось понимание, которого у меня не было, когда я задавал этот вопрос.
Ответ во многом зависит от размера памяти, доступной вашему процессу. Ваш системный администратор может ограничить объем виртуальной памяти, которую вам предоставит ОС (используя ulimit, который сохраняется в /etc/security), и в этом случае попытка сохранить что-то настолько большое будет неудачной. Однако если у вас меньше 21 ГБ физической памяти (возможно, существует еще один предел, о котором я либо не знаю, либо забыл), то при чтении 21 ГБ данных процесс начнет вызывать ошибку страницы. Сначала диспетчер памяти Linux попытается зарегистрировать сбой на страницах, которые являются резидентными, но в данный момент не используются. В отчаянии диспетчер памяти начнет подкачку данных на диск и обратно. Доступ к памяти обычно занимает менее 10 наносекунд (с современной оперативной памятью). Ошибка «чистой» страницы — это когда запрошенная виртуальная страница не находится в рабочем наборе, но постоянно находится в физической памяти; это может занять несколько микросекунд. Ошибка «грязной» страницы — это когда виртуальная страница не находится нигде в физической памяти и должна быть загружена с диска; это может занять несколько миллисекунд. Отнеситесь к этим цифрам с долей скептицизма, потому что на них влияют всевозможные переменные, зависящие от конфигурации.