如果我有一个适合 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/