2015-10-13 5 views
2

У меня есть большой ByteArray, х и хочу назначить кусочек его срез другого ByteArray, уломтика медленнее, используя memoryview (Python 3.5.0)

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] 

занимает 5 раз до тех пор, как y[::6] = x[:2*10**6:2]

  1. Могу ли я что-то отсутствует, или это замедление ошибка в Python?
  2. Каков самый быстрый способ сделать это в Python (a), если я хочу повторно назначить известное число 0 и (b) вообще?
+1

Я бы посмотрел на использование numpy для быстрых операций на больших числовых массивах. – interjay

ответ

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 

Последние два имеют дополнительное преимущество иметь очень небольшие накладные расходы памяти.