потребление памяти уфунком в арифметических выражениях - PullRequest
0 голосов
/ 25 мая 2018

Каково потребление памяти для арифметических выражений numpy, т.е.

vec ** 3 + vec ** 2 + vec

(vec - numpy.ndarray).Хранится ли массив для каждой промежуточной операции?Могут ли такие составные выражения иметь в несколько раз больше памяти, чем основной ndarray?

1 Ответ

0 голосов
/ 25 мая 2018

Вы правы, новый массив будет выделен для каждого промежуточного результата.К счастью, пакет numexpr предназначен для решения этой проблемы.Из описания:

Основная причина, по которой NumExpr достигает лучшей производительности, чем NumPy, заключается в том, что он избегает выделения памяти для промежуточных результатов.Это приводит к лучшему использованию кэша и уменьшает доступ к памяти в целом.Благодаря этому NumExpr лучше всего работает с большими массивами.

Пример:

In [97]: xs = np.random.rand(1_000_000)

In [98]: %timeit xs ** 3 + xs ** 2 + xs
26.8 ms ± 371 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [99]: %timeit numexpr.evaluate('xs ** 3 + xs ** 2 + xs')
1.43 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Благодаря @ max9111 за указание на то, что числоxpr упрощает умножение.Похоже, что большая часть расхождений в тесте объясняется оптимизацией xs ** 3.

In [421]: %timeit xs * xs
1.62 ms ± 12 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [422]: %timeit xs ** 2
1.63 ms ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [423]: %timeit xs ** 3
22.8 ms ± 283 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [424]: %timeit xs * xs * xs
2.52 ms ± 58.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
...