使用memoryview(Python 3.5.0)的切片分配速度较慢



我有一个大的字节数组x,想将它的一个切片分配给另一个字节数组y

x = bytearray(10**7) #something else in practice
y = bytearray(6*10**6)
y[::6] = x[:2*10**6:2]

我认为使用内存视图会更快,而且确实如此

memoryview(x)[:2*10**6:2]

非常快。 然而

y[::6] = memoryview(x)[:2*10**6:2]

所需时间是y[::6] = x[:2*10**6:2]的 5 倍

  1. 我错过了什么,还是这种减速是 Python 中的错误?
  2. 在 Python 中执行此操作的最快方法是什么 (a( 如果我想重复分配已知数量的 0,以及 (b( 一般来说?
减速并不是

一个错误,而是memoryview和缓冲区协议仍然相对较新,并且优化得很差。要y[::6] = memoryview(x)[:2*10**6:2]的基础代码在复制之前创建bytearray的连续副本。这意味着它将比直接创建和分配bytearray的正常切片慢。事实上,在这个特定实例中(在我的机器上(,使用 memoryview 的速度更接近于使用y[::6] = islice(x, None, 2*10**6, 2)而不是直接分配。

numpy已经存在了更长的时间,并且针对您感兴趣的操作类型进行了更好的优化。

使用 ipython:

In [1]: import numpy as np; from itertools import islice
In [2]: x = bytearray(10**7)
In [3]: y = bytearray(6*10**6)
In [4]: x_np = np.array(x)
In [5]: y_np = np.array(y)
In [6]: %timeit y[::6] = memoryview(x)[:2*10**6:2]
100 loops, best of 3: 10.9 ms per loop
In [7]: %timeit y[::6] = x[:2*10**6:2]
1000 loops, best of 3: 1.65 ms per loop
In [8]: %timeit y[::6] = islice(x, None, 2*10**6, 2)
10 loops, best of 3: 22.9 ms per loop
In [9]: %timeit y_np[::6] = x_np[:2*10**6:2]
1000 loops, best of 3: 911 µs per loop

最后两个具有内存开销非常小的额外好处。

相关内容

  • 没有找到相关文章

最新更新