msgpack 能否提供更好的性能和与 python 的 struct.pack() 相同的功能?

Posted

技术标签:

【中文标题】msgpack 能否提供更好的性能和与 python 的 struct.pack() 相同的功能?【英文标题】:can msgpack provide better performance and identical functionality of python's struct.pack()? 【发布时间】:2018-09-02 00:03:55 【问题描述】:

post 比较了许多序列化例程,表明 msgpack 比 Python 的 struct.pack() 和 unpack() 例程更快。我想使用 msgpack,但不知道如何以与 struct.pack() 等效的方式将 msgpack.packb() 用于浮点数或双精度数。

我需要通过 udp 从 python 将 N 个 double 发送到一个通过 udp/ip 读取 N 个 double 的 C/C++ 侦听器。无法修改 C/C++ 侦听器。 Python struct.pack() 方法与此剪辑一样适用于打包 N=3 双打:

import struct
import msgpack

packer = struct.Struct('ddd')
myTuple = (1.1, 2.2, 3.3)
packedData = packer.pack(*myTuple)

print(packedData) 产量:

b'\x9a\x99\x99\x99\x99\x99\xf1?\x9a\x99\x99\x99\x99\x99\x01@ffffff\n@'

然后用 msgpack 尝试同样的事情:

msgPackedData = msgpack.packb(myTuple)

和 print(msgPackedData) 产生:

b'\x93\xcb?\xf1\x99\x99\x99\x99\x99\x9a\xcb@\x01\x99\x99\x99\x99\x99\x9a\xcb@\nffffff'

输出显然不一样。使用 struct.pack() 发送的数据包被 udp 监听器完美地解释,但我想获得 msgpack 的性能改进。

在产生与struct.pack() 相同的输出时,能否获得 msgpack 的性能?

【问题讨论】:

【参考方案1】:

让我们比较两个打包的二进制文件。

上排是msgPackedData,下排是packedData

0x93 0xcb 0x3f 0xf1 0x99 0x99 0x99 0x99 0x99 0x9a 0xcb 0x40 0x01 0x99 0x99 0x99 0x99 0x99 0x9a 0xcb 0x40 0x0a 0x66 0x66 0x66 0x66 0x66 0x66 
          0x9a 0x99 0x99 0x99 0x99 0x99 0xf1 0x3f      0x9a 0x99 0x99 0x99 0x99 0x99 0x01 0x40      0x66 0x66 0x66 0x66 0x66 0x66 0x0a 0x40 

可以看到第一个 0x93 和三个 0xcb。这是什么?

MessagePack 包含类型信息。

0x93 表示 3 个元素的数组。 https://github.com/msgpack/msgpack/blob/master/spec.md#array-format-family

0xcb 表示大端 IEEE 754 双精度浮点数https://github.com/msgpack/msgpack/blob/master/spec.md#float-format-family

因此msgPackedDatapackedData 大4 个字节。

packedDatamsgPackedData 之间的另一个区别是字节顺序。但不影响大小。

如果您不使用元组,而只是打包三个双精度数,那么您可以删除第一个 0x93。但是没有办法删除0xcb。这是MessagePack格式中唯一的双数表达方式。

【讨论】:

所以答案是,不,没有办法使用 msgpack 生成与 'struct.pack()' 等效的输出?我很惊讶二进制和原始等选项不能提供相同结果的方法 似乎msgpack的性能优势只有在两端打包和解包时才能实现 正如您所评论的,答案是“否”。看来我们在使用struct.pack()的时候,需要知道完整的类型信息,而且两端都要匹配。 msgpack 是不同的。它包含 JSON 等类型信息。如果接收端不知道内容,他们可以在一定程度上处理数据。例如创建 JSON 输出。我认为,如果您选择 msgpack 作为高效 JSON 之类的东西,那就太好了。见msgpack.org。如果要最小的打包方式,msgpack 是不行的。我认为这是一种灵活性/尺寸选择。

以上是关于msgpack 能否提供更好的性能和与 python 的 struct.pack() 相同的功能?的主要内容,如果未能解决你的问题,请参考以下文章

Pandas msgpack vs 泡菜

MsgPack/Json性能数据

[.NET 开源] 高性能的 Swifter.MessagePack 已发布,并附带新版本的 Swifter.Json 和 Swifter.Data。

附近的人序列化之白送篇---msgpack大战protobuf

具有大量读写和与 Spark Structured Streaming 集成性能的数据存储

哪个蜂巢表提供更好的性能?