如何在python中正确使用Flatbuffers?

时间:2019-06-24 07:25:20

标签: python flatbuffers

关于在python中使用平面缓冲区,我有两个问题,它们集中在如何正确使用它们而不编写完全丧失其性能优势的代码的问题上。我想使用平面缓冲区在C#和python程序之间进行序列化和网络通信。我已经阅读了tutorialpython specifics和一些博客文章,这些博客文章将其他语言与FlatBuffers一起使用,但找不到适用于python的语言。

1。)Flatbuffers用于快速序列化。对于python来说甚至如此吗? python的performance仅表示“ Ok”,其他语言则表示“ Great”。缺少特定时间。我知道python通常不如C或C ++快,但是我们说话的速度有多慢?到它无法兑现的承诺的性能优势(例如,与JSON相比)?也许有人已经对python做过基准测试?如果没有,我将尝试编写一个比较C#和python之间的时间以及python中的flattbuffers与json的时间。

2。)速度很快,因为“零拷贝”。但是,这对于需要更改数据的程序意味着什么呢?特别是由于对象是不可变的。为了与它们一起工作,无论如何我都需要将这些值复制到对象的本地表示中。不会破坏这个目的吗?本教程说明了此示例以从FlatBuffer中读取内容:

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 个答案:

答案 0 :(得分:1)

  1. 您没有引用任何特定的链接。我猜想flatbuffers的性能将取决于调用API时来自Python的序列化。众所周知,Python比C或C ++慢。

  2. 关于零复制-Google(和Wikipedia)是您的朋友。

  3. 教程说“取决于语言”。您的意思表明在Python中您不会获得异常。

  4. 文档怎么说?您的实验确认了吗? (向我们展示解决问题的一些努力)

  5. 很难说。您尝试了什么,得到了什么结果?

答案 1 :(得分:1)

FlatBuffers的设计在获得最大速度方面非常喜欢C / C ++ / Rust之类的语言。 Python的实现模仿了这些语言的功能,但是对于Python来说这是很不自然的,因此,如果您纯粹是为Python设计的,那么它并不是最快的序列化程序设计。

我还没有对Python进行任何基准测试,但是Python特定的设计在许多情况下肯定会击败FlatBuffers-Python。 FlatBuffers设计甚至可以在Python中获胜的一种情况是,对于稀疏或随机访问的大文件,因为它实际上并不会一次解压缩所有数据。

您通常使用FlatBuffers是因为您以更快的语言拥有了堆栈性能的关键部分,然后您还希望能够在其他地方使用Python处理数据。但是,如果您仅使用Python工作,则FlatBuffers可能不是您的最佳选择(除非再次使用大型稀疏数据)。

当然,最好不要一开始就用Python做繁重的工作。

答案 2 :(得分:0)

我现在在python中建立了一个基准以比较JSON和flatbuffers,并认为答案可以使某人受益,所以我们开始:

设置如下:我们获得了客户端服务器体系结构(在同一台计算机上),都使用带套接字的python和asyncio。测试数据是一个大字典,其值包括字符串,数字和列表,其中包含其他字典,以及字符串,数字和列表值。该树最多可包含3个级别,每个列表约有100个对象。

flatbuffer模式将字典用于表,将向量用于列表,将结构用于仅使用float和int字段的字典。

flatbuffer 测试的测试数据为:

  • 填充到flatbuffer构建器中,并作为字节数组(序列化)返回
  • 通过套接字和异步读写器发送到服务器
  • 从字节数组转换回fb对象,服务器访问了一些字段(反序列化)
  • 反序列化时间将被发送回客户端。

JSON 测试的测试数据为:

  • 通过dumps()转换为字符串,然后转换为字节数组
  • 通过套接字和异步读写器发送到服务器
  • 从字节数组转换为字符串,然后通过json.loads()转换为字典;服务器访问的字段数相同(反序列化)
  • 反序列化时间将被发送回客户端。

我知道,关于设置有一些要争论的地方。例如,在平面缓冲区测试中不要将数据转换回dict。如果有人真的对此感兴趣,那么我可以进行这项测试。

但是现在来看结果:

--- 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

我的结论是,如果要快速编辑或创建数据,则不应在python中使用平面缓冲区。无法用python修改数据,这意味着每次发生更改时都必须重建FlatBuffer,这非常慢。

从好的方面来说,与JSON相比,读取数据非常快,并且字节大小非常小。因此,如果您有要发送或读取多次的静态数据,则可以使用平面缓冲区。