Я знаю, что раньше были некоторые вопросы, касающиеся чтения файлов, обработки двоичных данных и целочисленного преобразования с использованием struct
, поэтому я прихожу сюда, чтобы спросить о куске кода, который, по моему мнению, занимает слишком много времени для запуска. Читаемый файл представляет собой многоканальную запись данных (короткие целые числа) с интеркалированными интервалами данных (отсюда и вложенные операторы for
). Код выглядит следующим образом:
# channel_content is a dictionary, channel_content[channel]['nsamples'] is a string
for rec in xrange(number_of_intervals)):
for channel in channel_names:
channel_content[channel]['recording'].extend(
[struct.unpack( "h", f.read(2))[0]
for iteration in xrange(int(channel_content[channel]['nsamples']))])
С этим кодом я получаю 2,2 секунды на мегабайт для чтения с двухъядерным процессором с 2 МБ ОЗУ, и мои файлы обычно имеют 20+ МБ, что дает некоторую весьма раздражающую задержку (особенно если учесть еще одну условно-бесплатную программу, которую я пытаюсь отразить загружает файл ПУТЬ быстрее).
Что бы я хотел знать:
- Если есть какое-то нарушение «хорошей практики»: неправильно организованные циклы, повторяющиеся операции, которые занимают больше времени, чем необходимо, использование неэффективных типов контейнеров (словарей?) И т. Д.
- Если эта скорость чтения нормальная или нормальная к Python, и если скорость чтения
- Если создание скомпилированного расширения C ++ может повысить производительность, и если это будет рекомендуемый подход.
- (конечно) Если кто-то предлагает какую-либо модификацию этого кода, желательно на основе предыдущего опыта с аналогичными операциями.
Спасибо за чтение
(Я уже отправил несколько вопросов об этой моей работе, надеюсь, они все концептуально не связаны, и я также надеюсь, что не буду слишком повторяющимся.)
Редактировать: channel_names
- список, поэтому я сделал исправление, предложенное @eumiro (уберите опечатанные скобки)
Редактировать: В настоящее время я иду с предложением Себастьяна использовать array
с fromfile()
методом, и скоро поместит здесь окончательный код. Кроме того, каждый случай был очень полезен для меня, и я очень рад поблагодарить всех, кто любезно ответил.
Окончательная форма после ввода array.fromfile()
один раз и последующего попеременного расширения одного массива для каждого канала путем нарезки большого массива:
fullsamples = array('h')
fullsamples.fromfile(f, os.path.getsize(f.filename)/fullsamples.itemsize - f.tell())
position = 0
for rec in xrange(int(self.header['nrecs'])):
for channel in self.channel_labels:
samples = int(self.channel_content[channel]['nsamples'])
self.channel_content[channel]['recording'].extend(
fullsamples[position:position+samples])
position += samples
Улучшение скорости было очень впечатляющим по сравнению с чтением файла за раз или использованием struct
в любой форме.