【发布时间】:2018-05-05 03:18:03
【问题描述】:
我正在寻找快速替代我的功能的方法。目标是制作一个基于任意长度整数的 32 位整数列表。长度在 (value, bitlength) 的元组中明确给出。这是异步接口的 bit-banging 过程的一部分,每个总线事务需要 4 个 32 位整数。
所有整数都是无符号的,正数或零,长度可以在 0 到 2000 之间变化
我的输入是这些元组的列表, 输出应该是具有隐式 32 位长度的整数,位按顺序排列。其余不适合 32 的位也应返回。
input: [(0,128),(1,12),(0,32)]
output:[0, 0, 0, 0, 0x100000], 0, 12
我已经花了一两天时间对cProfile 进行分析,并尝试了不同的方法,但我似乎有点卡在在一秒钟内需要大约 100k 元组的函数上,这有点慢。理想情况下,我想要 10 倍的加速,但我没有足够的经验知道从哪里开始。这个速度的最终目标是超过每秒 4M 元组。
感谢您的任何帮助或建议。
我能做到的最快的是:
def foo(tuples):
'''make a list of tuples of (int, length) into a list of 32 bit integers [1,2,3]'''
length = 0
remlen = 0
remint = 0
i32list = []
for a, b in tuples:
n = (remint << (32-remlen)) | a #n = (a << (remlen)) | remint
length += b
if length > 32:
len32 = int(length/32)
for i in range(len32):
i32list.append((n >> i*32) & 0xFFFFFFFF)
remint = n >> (len32*32)
remlen = length - len32*32
length = remlen
elif length == 32:
appint = n & 0xFFFFFFFF
remint = 0
remlen = 0
length -= 32
i32list.append(appint)
else:
remint = n
remlen = length
return i32list, remint, remlen
这具有非常相似的性能:
def tpli_2_32ili(tuples):
'''make a list of tuples of (int, length) into a list of 32 bit integers [1,2,3]'''
# binarylist = "".join([np.binary_repr(a, b) for a, b in inp]) # bin(a)[2:].rjust(b, '0')
binarylist = "".join([bin(a)[2:].rjust(b, '0') for a, b in tuples])
totallength = len(binarylist)
tot32 = int(totallength/32)
i32list = [int(binarylist[i:i+32],2) for i in range(0, tot32*32, 32) ]
remlen = totallength - tot32*32
remint = int(binarylist[-remlen:],2)
return i32list, remint, remlen
【问题讨论】:
-
@martineau:抱歉,已修复。
-
可能的建议:切换到 pypy 并检查速度(注意:pypy JIT 编译器需要 long 时间来预热。至少在几秒钟的数据上运行它),然后开始挖掘 JIT 跟踪并查看是什么阻碍了您的代码,例如 here 。众所周知,python 中的函数调用会产生大量开销,所以如果可能的话,可以尝试让你的函数一次处理一大堆元组。或者也许看看 Cython。
标签: python