Как ускорить последовательную двоичную запись в Python

#python #numpy

#python #numpy

Вопрос:

Я хочу ускорить функцию Python, которая отвечает за запись чрезвычайно большого объема двоичных данных. На данный момент существует множество последовательных write вызовов, которые, как я подозреваю, замедляют выполнение. Мне не ясно, как ускорить это, потому что типы данных не совпадают между последовательными write вызовами. Представьте себе что-то вроде этого:

 with open("path/to/my/file.bin", "wb ") as f:
    while(True):
        data = data_queue.get()
        f.write(np.array(np.frombuffer(data[10:30], dtype=np.uint16)))
        if data[0] == 0:
            f.write(np.array([0, 1, 2], dtype=np.uint8))
            f.write(np.array([3, 4], dtype=np.uint16))
        elif data[0] == 1:
            f.write(np.array([5, 6, 7, 8], dtype=np.uint32))
        ...
        # A bunch of other conditional writes based off of what is in "data"
  

Есть ли простой способ объединить эти write вызовы, возможно, используя Pandas или Numpy, для ускорения записи в двоичный файл?

Комментарии:

1. Возможно, вы могли бы объединить байты массивов вне for цикла. Таким образом, вы могли бы сократить его до одного f.write .

2. Попробуйте увеличить размер буфера, например, open('...', "wb ", buffering=1024*1024) . Размер буфера по умолчанию (см. io.DEFAULT_BUFFER_SIZE ), вероятно, меньше, чем должен быть.

3. Количество вызовов f.write менее важно, чем количество низкоуровневых операций записи файлов, которые будут сбрасывать буфер на диск.

4. Это не станет намного быстрее, если вы удалите запись -> Это цикл Python и создание массива, которые являются ограничивающей частью. Можете ли вы предоставить немного больше информации о том, как выглядит ваш ввод (возможно, 4 простых numpy-массива, которые вы просто хотите сохранить в описанном вами формате? В этом случае может помочь структурированный массив numpy.

5. Я отредактировал пример кода, чтобы дать более представительный пример. В принципе, я жду в очереди получения данных, и я не знаю, что я собираюсь писать, пока не получу данные из очереди. Поэтому сложно заранее построить последовательность.