Какой оператор (+ vs + =) следует использовать для производительности? (На месте Vs не на месте)

Скажем, у меня есть два фрагмента кода в python:

1 --------------------------
import numpy as np
x = np.array([1,2,3,4])
y = x
x = x + np.array([1,1,1,1])
print y

2 --------------------------
import numpy as np
x = np.array([1,2,3,4])
y = x
x += np.array([1,1,1,1])
print y

Я думал, что результат y будет одинаковым в обоих примерах, так как y укажет на x и x станет (2,3,4,5), НО, это не было

Результаты были (1,2,3,4) for 1 и (2,3,4,5) for 2.

После некоторого исследования я выясню, что в первом примере

#-First example---------------------------------------
x = np.array([1,2,3,4]) # create x --> [1,2,3,4] 
y = x                   # made y point to x
# unril now we have x --> [1,2,3,4]
#                          |
#                          y
x = x + np.array([1,1,1,1]) 
# however this operation **create a new array** [2,3,4,5] 
# and made x point to it instead of the first one
# so we have y --> [1,2,3,4] and x --> [2,3,4,5]

#-Second example--------------------------------------
x = np.array([1,2,3,4]) # create x --> [1,2,3,4] 
y = x                   # made y point to x
# unril now the same x --> [1,2,3,4]
#                            |
#                            y
x += np.array([1,1,1,1])
# this operation **Modify the existing array**
# so the result will be
# unril now the same x --> [2,3,4,5]
#                            |
#                            y

Вы можете узнать больше об этом поведении (не только в этом примере) в этой ссылке Алгоритм на месте

Мой вопрос: осознавая это поведение, почему я должен использовать алгоритм на месте с точки зрения производительности? (время извлечения быстрее? меньше памяти alocation?..)

РЕДАКТИРОВАТЬ: Уточнение

Примером (+, = +) было просто объяснить просто локальный алгоритм тому, кто этого не знает.. но вопрос в целом заключался в использовании локального алгоритма не только в этом случае..

В качестве еще одного более сложного примера: загрузка CSV файла (всего 10 миллионов строк) в переменную, а затем сортировка результата, заключается в том, что идея локального алгоритма состоит в том, чтобы производить вывод в том же пространстве памяти, который содержит входные данные последовательно преобразовывая эти данные до тех пор, пока не будет произведен выход? - Это позволяет избежать необходимости использовать дважды хранилище - одну область для ввода и область равного размера для вывода (использование минимального объема ОЗУ, жесткого диска...)

Ответ 1

x = x + 1 vs x + = 1

Производительность

Кажется, что вы понимаете семантическую разницу между x += 1 и x = x + 1.

Для бенчмаркинга вы можете использовать timeit в IPython.

После определения этих функций:

import numpy as np
def in_place(n):
    x = np.arange(n)
    x += 1

def not_in_place(n):
    x = np.arange(n)
    x = x + 1

def in_place_no_broadcast(n):
    x = np.arange(n)
    x += np.ones(n, dtype=np.int)

Вы можете просто использовать синтаксис %timeit для сравнения характеристик:

%timeit in_place(10**7)
20.3 ms ± 81.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit not_in_place(10**7)
30.4 ms ± 253 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit in_place_no_broadcast(10**7)
35.4 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

not_in_place на 50% медленнее, чем in_place.

Обратите внимание, что broadcasting также имеет огромное значение: numpy понимает x += 1 как добавление 1 к каждому элементу x, не создавая еще один массив.

Предупреждение

in_place должна быть предпочтительной функцией: она быстрее и использует меньше памяти. Однако вы можете столкнуться с ошибками, если используете и изменяете этот объект в разных местах вашего кода. Типичный пример:

x = np.arange(5)
y = [x, x]
y[0][0] = 10
y
# [array([10,  1,  2,  3,  4]), array([10,  1,  2,  3,  4])]

Сортировка

Ваше понимание преимуществ сортировки на месте правильное. Это может существенно повлиять на требования к памяти при сортировке больших наборов данных.

Существуют и другие желательные функции для алгоритма сортировки (стабильная, приемлемая сложность худшего случая,...), и он похож на стандартный алгоритм Python (Timsort) многие из них.

Timsort - это гибридный алгоритм. Некоторые его части на месте, а некоторые требуют дополнительной памяти. Он никогда не будет использовать больше n/2, хотя.