Подтвердить что ты не робот

Почему NumPy массивы так быстро?

Я только что изменил программу, которую я пишу, чтобы хранить свои данные в виде массивов numpy, поскольку у меня были проблемы с производительностью, и разница была невероятной. Сначала потребовалось 30 минут, и теперь требуется 2,5 секунды!

Мне было интересно, как это происходит. Я предполагаю, что это потому, что он устраняет необходимость в циклах for, но помимо этого я тупик.

4b9b3361

Ответ 1

Массивные массивы представляют собой плотно упакованные массивы однородного типа. Напротив, списки Python представляют собой массивы указателей на объекты, даже если все они одного типа. Таким образом, вы получаете преимущества локальности ссылки.

Кроме того, многие операции Numpy реализованы на C, избегая общей стоимости циклов в Python, указателя на косвенное и динамическое титрование каждого элемента. Ускорение скорости зависит от того, какие операции вы выполняете, но на несколько порядков это не редкость в программах хруста числа.

Ответ 2

numpy массивы - это специализированные структуры данных. Это означает, что вы получаете не только преимущества эффективного представления в памяти, но и эффективные специализированные реализации.

Например, если вы суммируете два массива, сложение будет выполняться с помощью специализированных векторных операций ЦП, вместо вызова реализации Python для добавления int в цикле.

Ответ 3

У вас все еще есть петли, но они сделаны в c. Numpy основан на Atlas, который является библиотекой для операций линейной алгебры.

http://math-atlas.sourceforge.net/

Когда вы столкнулись с большим вычислением, он будет запускать тесты с использованием нескольких реализаций, чтобы узнать, какой из них самый быстрый на нашем компьютере в данный момент. При некоторых вычислениях numpy компультации могут быть распараллелены при множественном процессоре. Таким образом, вы будете иметь высокую оптимизацию c, работающую на непрерывных блоках памяти.

Ответ 4

Массивы Numpy чрезвычайно похожи на "нормальные" массивы, например, в c. Обратите внимание, что каждый элемент должен быть одного типа. Ускорение отлично, потому что вы можете воспользоваться предварительной выборкой, и вы можете мгновенно получить доступ к любому элементу массива с помощью индекса.

Ответ 5

Рассмотрим следующий код:

import numpy as np
import time

a = np.random.rand(1000000)
b = np.random.rand(1000000)

tic = time.time()
c = np.dot(a, b)
toc = time.time()

print("Vectorised version: " + str(1000*(toc-tic)) + "ms")

c = 0
tic = time.time()
for i in range(1000000):
    c += a[i] * b[i]
toc = time.time()

print("For loop: " + str(1000*(toc-tic)) + "ms")

Выход:

Vectorised version: 2.011537551879883ms
For loop: 539.8685932159424ms

Здесь Numpy намного быстрее, потому что он использует преимущества параллелизма (который имеет место в случае нескольких данных с одной инструкцией (SIMD)), в то время как традиционный цикл for не может его использовать.