【发布时间】:2020-12-05 06:27:38
【问题描述】:
我有一个非常长的字节串,比如这个(实际值可能是随机的):
in_var = b'\x01\x02\x03\x04\x05\x06...\xff'
我还有一个函数,它对一大块字节执行操作并返回相同数量的字节(本例中假设为 10 个字节):
def foo(chunk):
# do smth with chunk
# ......
return chunk
我想处理 in_var 和 foo() 处理所有 10 字节的块(如果最后剩余的字节少于 10 字节,则按原样发送最后一个块)并使用输出创建一个新变量 out_var。
我目前的做法耗时太长:
out_var = b''
for chunk in range(0, len(in_var), 10):
out_var += foo(in_var[chunk: chunk + 10])
函数foo() 每次运行只需要几分之一秒,所以总数应该非常快(总共 10 个块)。但是,我的时间要长一个数量级。
我也尝试过类似的结果:
import numpy as np
import math
in_var= np.array_split(np.frombuffer(in_var, dtype=np.uint8), math.ceil(len(in_var)/10))
out_var= b"".join(map(lambda x: foo(x), in_var))
foo() 在这个例子中只能处理 10 个字节(例如:它是一个具有固定块大小的加密函数),如果给它一个较小的块,它只是填充以使块 10 个字节。假设我无法控制它,foo() 只能处理 10 个字节的块。
有没有更快的方法来做到这一点?作为最后的手段,我可能不得不并行化我的代码,以便并行处理所有块......
谢谢!
更新:
显然我没有正确测量foo() 花费的时间。事实证明,foo() 占用了大部分时间,因此上面的评论数量级。再次感谢您的 cmets 和建议,但我确实做了一些改进。并行化代码似乎是正确的前进道路。
【问题讨论】:
-
out_var += foo(in_var[chunk: chunk + 10])重复的字符串连接很慢。 -
为什么要故意破坏性能,一次只调用 10 个字节的函数,而您可以执行更大的块? naive 解决方案比你复杂的解决方案快得多,我不得不想象你已经想到了一些你不能使用 fast naive 解决方案的原因,但你还没有告诉我们。
-
@JohnZwinck 假设我无法控制 foo(),它一次只能处理 10 个字节。我已经编辑了我的问题以明确说明