Мне нужно читать большие двоичные файлы байт за байтом, и я пытаюсь максимально ускорить это.
Я использую этот (далеко не идеальный) контекст таймера:
import time
from contextlib import contextmanager
@contextmanager
def timethis(label):
start = time.time()
try:
yield
finally:
end = time.time()
print('%s: %0.3f' % (label, end-start))
тогда у меня есть тестовая функция, которая перебирает заданный read_funcion
байт на байт.
def test(read_function):
with timethis(read_function.__name__):
# buffering seems to make no difference
# with DATA_PATH.open('br', buffering=8192) as file:
with DATA_PATH.open('br') as file:
for byte in read_function(file):
pass
my DATA_PATH
ist python 3.7.2 исходный код ...
from pathlib import Path
DATA_PATH = Path('~/Downloads/Python-3.7.2.tgz').expanduser()
теперь я сравнил две функции чтения (одна возвращает итератор с bytes
; вторая возвращает более длинный bytes
; итерирование по ним приведет к int
с)
def read1(file):
return iter(partial(file.read, 1), b"")
def read2(file):
for buffer in iter(partial(file.read, 8192), b""):
yield from buffer
когда я проверяю это с помощью
test(read1)
test(read2)
, я вижу существенные различия: вторая версия намного быстрее.
почему параметр буферизации в open
метод не дает такую же скорость, как мой ручной буферинг?Есть лучший способ сделать это?есть ли что-то в python, что делает это все для меня уже (я надеялся, что io.BufferedReader
будет - но оказывается, моя переменная file
уже BufferedReader
).