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

can msgpack provide better performance and identical functionality of python's struct.pack()?

post 比较了许多序列化例程,表明 msgpack 比 Python 的 struct.pack() 和 unpack() 例程更快。我想使用 msgpack 但无法弄清楚如何以与 struct.pack().

等效的方式将 msgpack.packb() 用于浮点数或双精度数

我需要通过 udp 从 pythonC/C++ 监听器发送 N 个双打通过 udp/ip 读取 N 个双打。 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 的性能?

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

上排为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 格式表示双数的方法。