Я думал, что f_dot будет медленнее, так как он должен был создать знаменатель временного массива, и я предположил, что этот шаг был пропущен f_no_dot.
Для чего стоит созданиевременный массив пропускается , поэтому f_no_dot
медленнее (но использует меньше памяти).
Поэлементные операции над массивами одинакового размера выполняются быстрее, потому что numpy невам нужно беспокоиться о шаге (размерах, размерах и т. д.) массивов.
Операции, использующие широковещательную передачу, обычно выполняются немного медленнее, чем операции, которые не обязаны.
Если выЕсли у вас есть свободная память, создание временной копии может дать вам ускорение, но будет использовать больше памяти.
Например, сравнивая эти три функции:
import numpy as np
import timeit
def f_no_dot(x, y):
return x / y
def f_dot(x, y):
denom = np.dot(y, np.ones((1,2)))
return x / denom
def f_in_place(x, y):
x /= y
return x
num = 3600000
x = np.ones((num, 2))
y = np.ones((num, 1))
for func in ['f_dot', 'f_no_dot', 'f_in_place']:
t = timeit.timeit('%s(x,y)' % func, number=100,
setup='from __main__ import x,y,f_dot, f_no_dot, f_in_place')
print func, 'time...'
print t / 100.0
Это дает аналогичные таймингиваши результаты:
f_dot time...
0.184361531734
f_no_dot time...
0.619203259945
f_in_place time...
0.585789341927
Однако, если мы сравним использование памяти, все станет немного яснее ...
Общий размер наших массивов x
и y
составляет около27,5 +55 МБ или 82 МБ (для 64-битных целых).Дополнительные затраты ~ 11 МБ накладываются на импорт импорта и т. Д.
Для возврата x / y
в качестве нового массива (т.е. без x /= y
) потребуется еще 55 МБ.
100 запусков f_dot
: Мы создаем здесь временный массив, поэтому мы ожидаем увидеть 11 + 82 + 55 + 55 МБ или ~ 203 МБ использования памяти.И вот что мы видим ... 
100 прогонов f_no_dot
: Если временный массив не создан, мы ожидаем пиковое использование памяти 11 + 82+ 55 МБ или 148 МБ ...
... это именно то, что мы видим.
Итак, x / y
- это , а не , создающий дополнительный num x 2
временный массив для деления.
Таким образом, деление занимает немного больше времени, чем оноесли бы он работал на двух массивах одинакового размера.
100 запусков f_in_place
: Если мы можем изменить x
на месте, мы можем сэкономить еще больше памяти,если это главная проблема.
По сути, в некоторых случаях numpy пытается сохранить память за счет скорости.