Чтение двоичного файла на Python:чтение определенных байтов занимает очень много времени
-
20-09-2019 - |
Вопрос
Это очень странно
Я читаю некоторые (по общему признанию, очень большие:~ 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 был одним из них, для протокола!), и он застревал там примерно на одинаковое количество времени при каждом запуске.
Есть какие-нибудь идеи?!
Спасибо,
Дункан
Решение
Хотя трудно сказать без какого-либо воспроизводимого образца, это звучит как проблема с буферизацией.Первая часть буферизуется, и пока вы не дойдете до конца буфера, она выполняется быстро;затем он замедляется до тех пор, пока не будет заполнен следующий буфер, и так далее.
Другие советы
Где вы храните результаты?Когда списки / dicts / что угодно становятся очень большими, может возникнуть заметная задержка, когда их необходимо перераспределить и изменить размер.
Может ли быть так, что вывоз мусора участвует ли в составлении списков ?
Добавленный:это забавные данные или блокнотно ?Что произойдет, если вы прочитаете блоки в случайном порядке, вдоль строк
r = range(4096)
random.shuffle(r) # inplace
for blockno in r:
file.seek( blockno * ... )
...