鉴于 Python 对缓冲协议的接口可以帮助减少制作临时数据副本的需要,我决定根据这个问题的答案memoryview
对它进行快速测试。
import time
expressions = ['list(b[i:i+1000])',
'list(b[i:])',
'b[i:]'
]
size = 1000000
x = b'x'*size
mv = memoryview(x)
for e in expressions:
print(f"Expression: {e}")
for b in (x, mv):
l = len(b)
start = time.time()
for i in range(0, l, 1000):
eval(e)
end = time.time()
print(f"Size: {size}, {type(b).__name__}, time: {end-start}")
结果:
$ python c:\temp\test_memoryview.py
Expression: list(b[i:i+1000])
Size: 1000000, bytes, time: 0.021999597549438477
Size: 1000000, memoryview, time: 0.03600668907165527
Expression: list(b[i:])
Size: 1000000, bytes, time: 5.3010172843933105
Size: 1000000, memoryview, time: 11.202003479003906
Expression: b[i:]
Size: 1000000, bytes, time: 0.2990117073059082
Size: 1000000, memoryview, time: 0.006985902786254883
前两个结果似乎是一个相当令人惊讶的结果。我知道调用列表将涉及数据的副本,但我认为在切片内存视图而不是底层字节数组时,您可以保存临时副本。