python - 将 int 拆分为字节的快速方法

标签 python python-3.x

如果我有一个适合 32 位的 int,在 python 中将它分成四个 8 位值的最快方法是什么?我的简单时序测试表明位屏蔽和移位比 divmod() 快一点,但我很确定我没有考虑到所有事情。

>>> timeit.timeit("x=15774114513484005952; y1, x =divmod(x, 256);y2,x = divmod(x, 256); y3, y4 = divmod(x, 256)")
0.5113952939864248
>>> timeit.timeit("x=15774114513484005952; y1=x&255; x >>= 8;y2=x&255; x>>=8; y3=x&255; y4= x>>8")
0.41230630996869877

在你问之前:这个操作会用到很多。我正在使用 python 3.4。

最佳答案

如果您经常这样做,最快的方法是创建一个专门的 Struct instance并预绑定(bind) pack 方法:

# Done once
int_to_four_bytes = struct.Struct('<I').pack

# Done many times (you need to mask here, because your number is >32 bits)
y1, y2, y3, y4 = int_to_four_bytes(x & 0xFFFFFFFF)

直接使用 struct.pack 将在第一次使用后使用缓存的 Struct 对象,但是您需要支付缓存查找成本才能从格式字符串转到缓存的 Struct 每次,这是次优的。通过创建和预绑定(bind) Struct 对象(在 CPython 中用 C 语言实现)的 pack,您可以绕过实际函数调用之外的所有 Python 字节码执行,并且无需花费缓存查找的时间。在我的机器上,它的运行时间约为 205 纳秒,而移位和掩码的运行时间为 267 纳秒(无需重新分配 x)。

另一种方法(对于更通用的,不是 struct 兼容的大小)是使用 int.to_bytes ;例如,在这种情况下:

y1, y2, y3, y4 = (x & 0xFFFFFFFF).to_bytes(4, 'big')

这与手动移位和屏蔽方法花费的时间大致相同(每个循环花费 268 ns),但可以更好地扩展到更大的字节数。

关于python - 将 int 拆分为字节的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35847673/

相关文章:

python - Scrapy - 抓取的网站身份验证 token 在抓取时过期

python - 如何跳过空关键字参数

python - 使用 tkinter 为单独的程序编写 Python UI。该程序的停止按钮基本上会卡住 UI 并继续执行脚本

python - 如何使用单个打印语句确定行索引?

python - Django Rest Framework JWT - 带有扩展用户的自定义负载

python - SSLCertificateError - 尝试从 facebook 获取访问 token 时出现 "The handshake operation timed out"

python - 文字冒险室运动

python-3.x - 在Python中对具有多个小数点的字典和字符串中的键进行排序

python - 更改 CSV 列中的数据格式

python - webbrowser.open() 断开链接(python 3.7)