Python中快速二进制数据转换
在Python中,将二进制数据字符串转换为数字值的最快方法是什么?
我现在使用的是struct.unpack_from()
,但是遇到了性能瓶颈。
背景:我正在处理一个混合了二进制和ASCII数据的输入流。ASCII数据的转换是通过C语言和ctypes来完成的。在C中实现解包的性能和使用unpack差不多。我猜是调用的开销太大了。我希望能找到一种类似C语言的原生转换方法(虽然这可能不太符合Python的风格)。很可能这些代码都需要转移到C语言中。
这个流是网络字节序(大端序),而我的机器是小端序。一个示例转换可能是:
import struct
network_stream = struct.pack('>I', 0x12345678)
(converted_int,) = struct.unpack_from('>I', network_stream, 0)
我对处理流格式不太关心,更关注的是二进制转换的一般情况,以及是否有其他替代unpack
的方法。例如,socket.ntohl()
需要一个整数,而int()
无法将二进制数据字符串转换为整数。
谢谢你的建议!
2 个回答
2
速度问题可能不是出在struct.unpack_from()
这个函数本身,而是Python在执行其他操作时需要做的事情,比如查找字典、创建对象、调用函数以及其他任务。如果你直接导入unpack_from
,而不是每次都从struct
模块里获取,可以稍微加快一点速度,因为这样可以省去一次字典查找。
$ python -m timeit -s "import struct; network_stream = struct.pack('>I', 0x12345678)" "(converted_int,) = struct.unpack_from('>I', network_stream, 0)"
1000000 loops, best of 3: 0.277 usec per loop
$ python -m timeit -s "import struct; from struct import unpack_from; network_stream = struct.pack('>I', 0x12345678)" "(converted_int,) = unpack_from('>I', network_stream, 0)"
1000000 loops, best of 3: 0.258 usec per loop
不过,如果你需要处理很多解析逻辑,每次都要一个一个地拆解数字,这样就无法一次性处理一整组数据,那么无论你用什么方法来实现,效果都差不多。你可能需要在一些开销更小的语言中完成这个内部循环,比如C语言。