ti-enxame.com

Por que as matrizes NumPy são tão rápidas?

Acabei de alterar um programa que estou escrevendo para manter meus dados em matrizes numpy, pois eu estava tendo problemas de desempenho, e a diferença era incrível. Inicialmente, levou 30 minutos para ser executado e agora leva 2,5 segundos!

Fiquei me perguntando como isso acontece. Suponho que é porque remove a necessidade de for loops, mas além disso estou perplexo.

51
Anake

Matrizes numpy são matrizes densamente compactadas do tipo homogêneo. Python, por outro lado, são matrizes de ponteiros para objetos, mesmo quando todos são do mesmo tipo. Portanto, você obtém os benefícios de localidade de referência .

Além disso, muitas operações Numpy são implementadas em C, evitando o custo geral de loops em Python, indireção de ponteiro e verificação de tipo dinâmico por elemento. O aumento da velocidade depende de quais operações você está executando, mas algumas ordens de magnitude não são incomuns em programas de processamento de números.

79
Fred Foo

matrizes numpy são estruturas de dados especializadas. Isso significa que você não apenas obtém os benefícios de uma representação eficiente na memória, mas implementações especializadas eficientes também.

Por exemplo. se você estiver resumindo duas matrizes, a adição será realizada com as operações especializadas do vetor da CPU , em vez de chamar o python = implementação da adição int em um loop.

15
riffraff

Você ainda tem loops, mas eles são feitos em c. O Numpy é baseado no Atlas, que é uma biblioteca para operações de álgebra linear.

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

Ao enfrentar um grande cálculo, ele executa testes usando várias implementações para descobrir qual é a mais rápida em nosso computador no momento. Com algumas construções numpy, as comutações podem ser paralelizadas em vários cpus. Portanto, você terá um c altamente otimizado executando em blocos de memória contínua.

1
Simon Bergot

Considere o seguinte código:

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")

Resultado:

Vectorised version: 2.011537551879883ms
For loop: 539.8685932159424ms

Aqui, o Numpy é muito mais rápido, porque tira vantagem do paralelismo (que é o caso do SIMD), enquanto o loop for tradicional não pode usá-lo.

1
VinKrish

Matrizes numpy são extremamente semelhantes às matrizes 'normais', como as de c. Observe que todo elemento deve ser do mesmo tipo. A aceleração é ótima porque você pode tirar proveito da pré-busca e acessar instantaneamente qualquer elemento da matriz por seu índice.

0
ScarletAmaranth