使用memoryview减慢切片分配(Python 3.5.0)

时间:2015-10-13 03:43:14

标签: python python-3.5 memoryview

我有一个大的bytearray x,并希望将它的一个切片分配给另一个bytearray的切片y

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

我认为使用memoryview会更快,而且确实

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)一般?

1 个答案:

答案 0 :(得分:1)

减速并不是一个错误,但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

最后两个具有额外的好处,即内存开销很小。