Je viens de réaliser que faire
x.real*x.real+x.imag*x.imag
est trois fois plus rapide que de faire
abs(x)**2
où x est un tableau numpy de nombres complexes. Pour la lisibilité du code, je pourrais définir une fonction telle que
def abs2(x):
return x.real*x.real+x.imag*x.imag
ce qui est toujours beaucoup plus rapide que abs(x)**2, mais au prix d'un appel de fonction. Est-il possible de mettre en ligne une telle fonction, comme je le ferais en C en utilisant une macro ou le mot-clé inline ?
14 votes
Si vous avez besoin de ce genre d'optimisations, vous devez probablement utiliser quelque chose comme Cython.
8 votes
PyPy à la rescousse !
12 votes
Si vous vous souciez de ces petites optimisations, vous devriez utiliser le C, pas Python. Python n'a rien à voir avec la vitesse, vraiment.
2 votes
Avez-vous essayé de chronométrer l'instruction par rapport à l'appel de fonction pour voir s'il y a vraiment une différence ?
3 votes
En plus de ce qui est très correct et important (sérieusement, écoutez-les), notez qu'en raison de la nature dynamique de Python, le seul moment où l'inlining pourrait se produire est au moment de l'exécution. C'est l'une des nombreuses optimisations que fait PyPy (bien qu'il n'y ait pas encore de NumPy complet, mais au moins on y travaille), et PyPy fonctionne mieux sur du code Python idiomatique, pas sur du code écrit pour raser de minuscules bouts de temps de la surcharge d'exécution.
0 votes
@vartec : J'ai mesuré la même chose pour les petits tableaux (100 éléments). Pour les grands tableaux (10000 éléments), par contre, il a probablement raison.
1 votes
Il est évident que l'extraction de la racine carrée est beaucoup plus lente que de faire deux multiplications et une addition. Pourquoi ne pas simplement
x*x.conj()
d'ailleurs ?2 votes
@MarkRansom Les appels de fonctions Python sont notoirement coûteux, c'est le prix à payer pour les capacités monkey-Parcheando de Python, etc. stackoverflow.com/a/54524575/257645