Permet de commencer avec trois tableaux de dtype=np.double
. Les Timings sont exécutées sur un PROCESSEUR intel à l'aide de numpy 1.7.1 compilé avec icc
et lié à intel mkl
. Un cpu AMD avec numpy 1.6.1 compilé avec gcc
sans mkl
a également été utilisé pour vérifier les horaires. Veuillez noter les horaires d'échelle près linéairement avec la taille du système et ne sont pas dues à la faible surcharge engagés dans les fonctions de numpy if
des déclarations de ces différences apparaîtront dans microsecondes pas millisecondes:
arr_1D=np.arange(500,dtype=np.double)
large_arr_1D=np.arange(100000,dtype=np.double)
arr_2D=np.arange(500**2,dtype=np.double).reshape(500,500)
arr_3D=np.arange(500**3,dtype=np.double).reshape(500,500,500)
La première permet de regarder le np.sum
fonction de:
np.all(np.sum(arr_3D)==np.einsum('ijk->',arr_3D))
True
%timeit np.sum(arr_3D)
10 loops, best of 3: 142 ms per loop
%timeit np.einsum('ijk->', arr_3D)
10 loops, best of 3: 70.2 ms per loop
Pouvoirs:
np.allclose(arr_3D*arr_3D*arr_3D,np.einsum('ijk,ijk,ijk->ijk',arr_3D,arr_3D,arr_3D))
True
%timeit arr_3D*arr_3D*arr_3D
1 loops, best of 3: 1.32 s per loop
%timeit np.einsum('ijk,ijk,ijk->ijk', arr_3D, arr_3D, arr_3D)
1 loops, best of 3: 694 ms per loop
Produit extérieur:
np.all(np.outer(arr_1D,arr_1D)==np.einsum('i,k->ik',arr_1D,arr_1D))
True
%timeit np.outer(arr_1D, arr_1D)
1000 loops, best of 3: 411 us per loop
%timeit np.einsum('i,k->ik', arr_1D, arr_1D)
1000 loops, best of 3: 245 us per loop
Tous les ci-dessus sont deux fois plus rapide avec l' np.einsum
. Ceux-ci devraient être des pommes à des pommes de comparaisons comme tout ce qui est spécifiquement de l' dtype=np.double
. J'attendrais la vitesse dans une opération comme celle-ci:
np.allclose(np.sum(arr_2D*arr_3D),np.einsum('ij,oij->',arr_2D,arr_3D))
True
%timeit np.sum(arr_2D*arr_3D)
1 loops, best of 3: 813 ms per loop
%timeit np.einsum('ij,oij->', arr_2D, arr_3D)
10 loops, best of 3: 85.1 ms per loop
Einsum semble être au moins deux fois plus rapide pour np.inner
, np.outer
, np.kron
, et np.sum
, indépendamment de l' axes
sélection. La principale exception étant l' np.dot
comme elle les appelle DGEMM à partir d'une bibliothèque BLAS. Alors, pourquoi est - np.einsum
plus rapide que les autres fonctions de numpy qui sont équivalents?
Le DGEMM cas pour l'exhaustivité:
np.allclose(np.dot(arr_2D,arr_2D),np.einsum('ij,jk',arr_2D,arr_2D))
True
%timeit np.einsum('ij,jk',arr_2D,arr_2D)
10 loops, best of 3: 56.1 ms per loop
%timeit np.dot(arr_2D,arr_2D)
100 loops, best of 3: 5.17 ms per loop
Le leader de la théorie de @sebergs commentaire qu' np.einsum
pouvez faire usage de SSE2, mais numpy est ufuncs ne sera pas jusqu'à ce que numpy 1.8 (voir le journal des modifications). Je crois que c'est la bonne réponse, mais n'ont pas été en mesure de le confirmer. Certains ont limité la preuve peut être trouvée par la modification de la dtype de tableau d'entrée, et en observant la différence de vitesse et le fait que pas tout le monde observe les mêmes tendances dans les horaires.