web-dev-qa-db-fra.com

Les fonctions mathématiques de NumPy sont-elles plus rapides que Python?

J'ai une fonction définie par une combinaison de fonctions mathématiques de base (abs, cosh, sinh, exp, ...).

Je me demandais si cela faisait une différence (en vitesse) d'utiliser, par exemple, numpy.abs() au lieu de abs()?

57
Mermoz

Voici les résultats du timing:

lebigot@weinberg ~ % python -m timeit 'abs(3.15)' 
10000000 loops, best of 3: 0.146 usec per loop

lebigot@weinberg ~ % python -m timeit -s 'from numpy import abs as nabs' 'nabs(3.15)'
100000 loops, best of 3: 3.92 usec per loop

numpy.abs() est plus lent que abs() car il gère également les tableaux Numpy: il contient du code supplémentaire qui offre cette flexibilité.

Cependant, Numpy est rapide sur les tableaux:

lebigot@weinberg ~ % python -m timeit -s 'a = [3.15]*1000' '[abs(x) for x in a]'
10000 loops, best of 3: 186 usec per loop

lebigot@weinberg ~ % python -m timeit -s 'import numpy; a = numpy.empty(1000); a.fill(3.15)' 'numpy.abs(a)'
100000 loops, best of 3: 6.47 usec per loop

(PS: '[abs(x) for x in a]' est plus lent en Python 2,7 que le meilleur map(abs, a), qui est environ 30% plus rapide - ce qui est encore beaucoup plus lent que NumPy. )

Ainsi, numpy.abs() ne prend pas beaucoup plus de temps pour 1000 éléments que pour 1 flottant unique!

73
Eric O Lebigot

Vous devez utiliser la fonction numpy pour gérer les types de numpy et utiliser la fonction python régulière pour traiter les types python réguliers).

Les pires performances se produisent généralement lors du mélange de python prédéfinis avec numpy, en raison de la conversion des types. Ces types de conversion ont été optimisés récemment, mais il est souvent préférable de ne pas les utiliser. Bien sûr, votre kilométrage peut varier , utilisez donc des outils de profilage pour comprendre.

Pensez également à utiliser des programmes comme cython ou à créer un module C si vous souhaitez optimiser davantage votre programme. Ou pensez à ne pas utiliser python lorsque les performances comptent.

mais, lorsque vos données ont été placées dans un tableau numpy, numpy peut être très rapide pour calculer des tas de données.

25
BatchyX

En fait, sur un tableau numpy

construit dans abs appelle l'implémentation de numpy via __abs__, voir Pourquoi les fonctions intégrées comme abs fonctionnent sur le tableau numpy?

Donc, en théorie, il ne devrait pas y avoir beaucoup de différence de performances.

import timeit

x = np.random.standard_normal(10000)

def pure_abs():
    return abs(x)

def numpy_abs():
    return np.absolute(x)

n = 10000

t1 = timeit.timeit(pure_abs, number = n)
print 'Pure Python abs:', t1
t2 = timeit.timeit(numpy_abs, number = n)
print 'Numpy abs:', t2
Pure Python abs: 0.435754060745
Numpy abs: 0.426516056061
5
colinfang