Чтение двоичного файла в Python: чтение определенных байтов занимает очень много времени - PullRequest
0 голосов
/ 15 февраля 2010

Это очень странно

Я читаю некоторые (по общему признанию, очень большие: ~ 2 ГБ каждый) двоичные файлы с использованием библиотек numpy в Python. Я использую:

thingy = np.fromfile(fileObject, np.int16, 1)

метод. Это прямо в середине вложенного цикла - я делаю этот цикл 4096 раз на каждый «канал», и этот «канальный» цикл 9 раз для каждого «приемника», а этот «приемный» цикл 4 раза (есть 9 каналов за получателя, которых 4!). Это для каждого «блока», из которых ~ 3600 на файл.

Итак, вы можете видеть, очень итеративно, и я знаю, что это займет много времени, но это заняло ОЧЕНЬ больше, чем я ожидал - в среднем 8,5 секунд на «блок».

Я провел несколько тестов, используя time.clock () и т. Д., И обнаружил, что все идет так же быстро, как и должно быть, за исключением примерно 1 или 2 выборок на «блок» (1 или 2 в 4096 * 9 * 4) Казалось бы, он застрял на несколько секунд. Теперь это должен быть случай возврата простого int16 из двоичного файла, а не того, что должно занимать секунды ... почему он зависает?

По результатам бенчмаркинга я обнаружил, что он каждый раз торчал в одном и том же месте (блок 2, приемник 8, канал 3, образец 1085 был одним из них, для записи!), И он застревал там примерно одинаковое количество времени на каждый прогон.

Есть идеи?!

Спасибо

Duncan

Ответы [ 3 ]

3 голосов
/ 15 февраля 2010

Хотя трудно сказать без какого-либо воспроизводимого семпла, это звучит как проблема буферизации. Первая часть буферизуется, и пока вы не достигнете конца буфера, это быстро; затем он замедляется до заполнения следующего буфера и т. д.

2 голосов
/ 15 февраля 2010

Где вы храните результаты? Когда списки / дикты / что-либо очень большое, может произойти заметная задержка, когда они должны быть перераспределены и изменены.

1 голос
/ 15 февраля 2010

Может ли быть так, что сборщик мусора запускает списки?

Добавлено: смешные данные или блочные? Что произойдет, если вы читаете блоки в случайном порядке вдоль строк

r = range(4096)
random.shuffle(r)  # inplace
for blockno in r:
    file.seek( blockno * ... )
    ...
...