Я запускаю скрипт Python v3.5 на Raspberry Pi с камерой.Программа включает в себя запись видео с picamera
и выборку кадра из видеопотока для выполнения операций над ним.Иногда на обработку байтового буфера уходит очень много времени (20+ с).Упрощенная версия кода содержит проблемную область:
import io
import picamera
camera = picamera.PiCamera()
camera.start_recording("/path/to/file.h264")
cnt = 0
while True:
if cnt > 30:
stream = io.BytesIO()
camera.capture(stream, use_video_port=True, resize=(1920, 1080), format='rgba')
cnt = 0
else:
cnt += 1
Через некоторое время время, затрачиваемое на открытие потока, сходит с ума.В моем последнем заезде один экземпляр занял 48 секунд! На этом рисунке показан график времени открытия потока байтов для каждого цикла. Я выполнил проверку синхронизации для каждой строки в проблемной области кода, и я могу подтвердить, что это stream = io.BytesIO()
строка, вызывающая задержки.
Когда я наблюдаю за процессором и памятью Raspberry Pi во время этой задачи, используя psutils
, я не вижу никаких очевидных проблем.Загрузка ЦП составляет 10-15%, виртуальной памяти - ~ 24,2%, используется подкачка 0.
Кроме программы Python, на Pi не выполняются никакие другие пользовательские процессы.На оборудовании установлена стандартная Raspbian установка с графическим интерфейсом.
Поскольку программа Python содержит более 1000 строк, я не собираюсь включать в этот текст вопроса ничего, кроме минимального примера.Если вы хотите посмотреть на него контекстную информацию, , пожалуйста, взгляните на этот список с кодом .
Предварительные поиски показывают, что это известная проблема с BytesIO.Некоторые старые исправления ошибок (около 2014 г.) для Python предполагают, что это было улучшено в некоторых случаях в версии 3.5.
Вопросы:
- Почему
BytesIO
медленный здесь? - Есть ли альтернативный способ потоковой передачи байтов, который быстрее?
- Есть ли лучший способ использовать
BytesIO
, чтобы получить то, что мне нужно?
РЕДАКТИРОВАТЬ: я добавил строку в цикл, заставляя поток закрываться в конце каждого процесса, используяstream.close()
, но, похоже, это было неэффективно.У меня все еще было время открытия потока 20+ секунд.
EDIT_2: я неправильно прочитал значения в тесте из отредактированной информации и пропустил, что значения имели научное обозначение.