Как правильно использовать flatbuffers в python? - PullRequest
0 голосов
/ 24 июня 2019

У меня есть два вопроса, касающихся использования плоских буферов в python, которые сосредоточены вокруг того, как правильно их использовать без написания кода, который полностью лишает его преимущества в производительности. Я хочу использовать flatbuffers для сериализации и сетевого взаимодействия между C # и python-программой. Я прочитал учебник , особенности Python и некоторые посты, которые используют другие языки с плоскими буферами, но не могут найти один для Python.

1.) Плоские буферы предназначены для быстрой сериализации. Это правда даже для питона? Производительность для python просто говорит "Ок", где другие языки получают "Отлично". Конкретные времена отсутствуют. Я знаю, что Python, как правило, не так быстр, как C или C ++, но как медленно мы говорим? До такой степени, что он побеждает обещанное преимущество в производительности (например, по сравнению с JSON)? Может быть, кто-то уже сделал тест с python? Если нет, я постараюсь написать один, который сравнивает времена между C # и python, а также flattbuffers против json в python.

2.) Это быстро, из-за "нулевой копии". Но что это значит для программы, которая должна изменить данные? Тем более что объекты неизменны. Чтобы работать с ними, мне все равно нужно скопировать значения в мое локальное представление объектов. Не победить эту цель? Учебное пособие заявляет этот пример для чтения из плоского буфера:

import MyGame.Example as example
import flatbuffers
buf = open('monster.dat', 'rb').read()
buf = bytearray(buf)
monster = example.GetRootAsMonster(buf, 0)
hp = monster.Hp()
pos = monster.Pos()

Разве эти последние две строки не являются копиями?

Ответы [ 3 ]

1 голос
/ 24 июня 2019

Конструкция FlatBuffers сильно благоприятствует языкам, таким как C / C ++ / Rust, в достижении максимальной скорости.Реализация Python имитирует то, что делают эти языки, но это очень неестественно для Python, поэтому это не самый быстрый возможный дизайн сериализатора, который вы получили бы, если бы разрабатывали исключительно для Python.

Я ничего не тестировалPython, но дизайн, специфичный для Python, во многих случаях наверняка превзойдет FlatBuffers-Python.Один из случаев, когда дизайн FlatBuffers выигрывает даже в Python, касается больших файлов, доступ к которым осуществляется редко или случайно, поскольку он фактически не распаковывает все данные сразу.

Обычно вы используете FlatBuffers, потому что у вас есть производительностькритическая часть вашего стека на более быстром языке, и тогда вы также захотите иметь возможность обрабатывать данные в Python в другом месте.Однако, если вы работаете исключительно в Python, FlatBuffers, возможно, не лучший выбор (если, опять же, вы не работаете с большими разреженными данными).

Лучше, конечно, не делать тяжелую работу в Python..

1 голос
/ 24 июня 2019
  1. Вы не ссылаетесь на какую-либо конкретную ссылку. Я предполагаю, что производительность flatbuffers будет зависеть от сериализации из Python при вызове API. Известно, что Python медленнее, чем, скажем, C или C ++.

  2. Относительно нулевой копии - Google (и Wikipedia ) - ваш друг.

  3. В учебнике написано "в зависимости от языка". То, что вы говорите, говорит о том, что в Python вы не получите исключений.

  4. Что говорится в документации? Ваши эксперименты подтверждают это? (покажите нам некоторые усилия по решению проблемы)

  5. Трудно сказать. Что вы пробовали и какие у вас результаты?

0 голосов
/ 03 июля 2019

Теперь я сделал тест в python, чтобы сравнить JSON и flatbuffers, и думаю, что ответ может кому-то помочь, поэтому мы идем:

Настройка выглядит следующим образом: Мы получили архитектуру клиент-сервер (на том жемашина), как в питоне с розетками и asyncio.Тестовые данные - это большой словарь со значениями в виде строк, чисел и списков, которые содержат другие словари, в том числе со строковыми, числовыми и списочными значениями.Это дерево имеет до 3 уровней в глубину, около 100 объектов в списке.

В схеме flatbuffer используются таблицы для диктов, векторы для списков и структуры для диктов, в которых используются только поля float и int.

Тестовые данные для теста flatbuffer :

  • заполнены в конструкторе flatbuffer и возвращены как байтовый массив (сериализация)
  • , отправленный на сервер через сокети asyncio reader / writer
  • , преобразованный из bytearray обратно в fb-объект, и сервер обращается к нескольким полям (десериализация)
  • время десериализации затем отправляется обратно клиенту.

Тестовые данные для теста JSON :

  • преобразуются в строку с помощью функции dumps () и затем преобразуются в байтовый массив
  • отправляется на сервер через сокет и asyncio reader / writer
  • , преобразованный из bytearray в строку, а затем через json.loads () обратно в словарь;чем те же несколько полей доступны серверу (десериализация)
  • время десериализации отправляется обратно клиенту.

Я знаю, что есть некоторые моменты, которые можноспорить о настройке.Например, не преобразовывать данные обратно в dict в тесте flatbuffer.Если кто-то действительно заинтересован в этом, я мог бы продвинуться в этом тесте.

Но теперь перейдем к результатам:

--- flatbuffers  ---
roundtrip time:   7.010654926300049
serialize time:   6.960820913314819
deserialize time: 0.0
size in byte:     6.365.432
---     json     ---
roundtrip time:   0.7860651016235352
serialize time:   0.3211710453033447
deserialize time: 0.28783655166625977
size in byte:     13.946.172

Мой вывод состоит в том, что не следует использовать flatbuffers в Python, еслиВы хотите быстро редактировать или создавать данные.В Python нет способа изменить данные, а это означает, что вам придется перестраивать плоский буфер каждый раз, когда что-то меняется, и это очень медленно.

С другой стороны, очень быстро читать данные иразмер байта очень низкий по сравнению с JSON.Поэтому, если у вас есть статические данные, которые вы хотите многократно отправлять или считывать, решением могут стать плоские буферы.

...