繁体   English   中英

Python中的快速二进制数据转换

[英]fast binary data conversion in Python

在Python中将二进制数据字符串转换为数值的最快方法是什么?

我正在使用struct.unpack_from() ,但是达到了性能限制。

上下文:传入流是混合二进制和ASCII数据。 ASCII数据转换是通过ctypes在C中完成的。 通过ctypes在C中实现解包产生了与解包相似的性能。 我的猜测是呼叫开销太大了。 我希望找到一种原生的类C强制方法(但不是Pythonic)。 很可能所有这些代码都需要转移到C.

流是网络字节顺序(big-endian),机器是little-endian。 转换的示例是:

import struct
network_stream = struct.pack('>I', 0x12345678)
(converted_int,) = struct.unpack_from('>I', network_stream, 0) 

我不太关心处理流格式,而不是二进制转换的一般情况,如果甚至unpack的替代方案。 例如, socket.ntohl()需要一个int,而int()不会转换二进制数据字符串。

谢谢你的建议!

根据我的经验,您需要将代码移动到C是正确的。正如您发现用于二进制转换的各种工具(例如structctypes )的性能具有大致相似的性能。

Cython是为Python生成C扩展的最简单方法。

另一个简单的方法是放弃CPython完全支持pypy ,它可以使用跟踪JIT生成高质量,低级别的代码。

更具挑战性但更直接的方法是编写一个普通的C扩展。 这不好玩,但并不难。

速度问题可能不是在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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM