Quelques points de base:
- Les appels de méthode Python sont "coûteux" en raison de leur nature interprétée . En théorie, si votre code est assez simple, la décomposition du code Python a un impact négatif en plus de la lisibilité et de la réutilisation ( ce qui est un gros gain pour les développeurs, pas tant pour les utilisateurs ).
- Le principe de responsabilité unique (SRP) maintient le code lisible, est plus facile à tester et à maintenir.
- Le projet a un arrière-plan spécial où nous voulons du code lisible, des tests et des performances temporelles.
Par exemple, un code comme celui-ci qui appelle plusieurs méthodes (x4) est plus lent que le suivant qui n'en est qu'une.
from operator import add
class Vector:
def __init__(self,list_of_3):
self.coordinates = list_of_3
def move(self,movement):
self.coordinates = list( map(add, self.coordinates, movement))
return self.coordinates
def revert(self):
self.coordinates = self.coordinates[::-1]
return self.coordinates
def get_coordinates(self):
return self.coordinates
## Operation with one vector
vec3 = Vector([1,2,3])
vec3.move([1,1,1])
vec3.revert()
vec3.get_coordinates()
Par rapport à cela:
from operator import add
def move_and_revert_and_return(vector,movement):
return list( map(add, vector, movement) )[::-1]
move_and_revert_and_return([1,2,3],[1,1,1])
Si je dois paralléliser quelque chose comme ça, c'est assez objectif de perdre des performances. Attention, ce n'est qu'un exemple; mon projet a plusieurs mini routines avec des mathématiques comme ça - Bien qu'il soit beaucoup plus facile de travailler avec, nos profileurs ne l'aiment pas.
Comment et où adopter le SRP sans compromettre les performances en Python, car sa mise en œuvre inhérente le touche directement?
Existe-t-il des solutions de contournement, comme une sorte de pré-processeur qui met les choses en ligne pour la sortie?
Ou est-ce que Python est tout simplement mauvais pour gérer la panne de code?
Réponses:
Malheureusement oui, Python est lent et il existe de nombreuses anecdotes sur les gens qui augmentent considérablement les performances en insérant des fonctions et en rendant leur code laid.
Il existe un travail autour, Cython, qui est une version compilée de Python et beaucoup plus rapide.
- Modifier Je voulais juste répondre à certains des commentaires et autres réponses. Bien que leur objectif ne soit peut-être pas spécifique à Python. mais une optimisation plus générale.
N'optimisez pas jusqu'à ce que vous ayez un problème, puis recherchez les goulots d'étranglement
Généralement de bons conseils. Mais l'hypothèse est que le code «normal» est généralement performant. Ce n'est pas toujours le cas. Les langages et les cadres individuels ont chacun leurs propres particularités. Dans ce cas, les appels de fonction.
Ce n'est que quelques millisecondes, d'autres choses seront plus lentes
Si vous exécutez votre code sur un ordinateur de bureau puissant, vous ne vous en souciez probablement pas tant que votre code d'utilisateur unique s'exécute en quelques secondes.
Mais le code métier a tendance à fonctionner pour plusieurs utilisateurs et nécessite plus d'une machine pour prendre en charge la charge. Si votre code s'exécute deux fois plus vite, cela signifie que vous pouvez avoir deux fois plus d'utilisateurs ou la moitié du nombre de machines.
Si vous êtes propriétaire de vos machines et de votre centre de données, vous disposez généralement d'une grande partie des frais généraux liés à la puissance du processeur. Si votre code est un peu lent, vous pouvez l'absorber, au moins jusqu'à ce que vous ayez besoin d'acheter une deuxième machine.
En ces jours de cloud computing où vous n'utilisez que la puissance de calcul dont vous avez besoin et pas plus, il y a un coût direct pour le code non performant.
L'amélioration des performances peut réduire considérablement les dépenses principales d'une entreprise basée sur le cloud et les performances devraient être au premier plan.
la source
De nombreux problèmes de performances potentiels ne sont pas vraiment un problème dans la pratique. Le problème que vous soulevez peut être l'un d'entre eux. Dans la langue vernaculaire, nous appelons s'inquiéter de ces problèmes sans preuve qu'il s'agit de problèmes réels d' optimisation prématurée.
Si vous écrivez un frontal pour un service Web, vos performances ne seront pas affectées de manière significative par les appels de fonction, car le coût d'envoi de données sur un réseau dépasse de loin le temps nécessaire pour effectuer un appel de méthode.
Si vous écrivez une boucle serrée qui rafraîchit un écran vidéo soixante fois par seconde, cela peut avoir de l'importance. Mais à ce stade, je prétends que vous avez des problèmes plus importants si vous essayez d'utiliser Python pour ce faire, un travail pour lequel Python n'est probablement pas bien adapté.
Comme toujours, la façon dont vous le découvrez est de mesurer. Exécutez un profileur de performances ou des minuteurs sur votre code. Voyez si c'est un vrai problème dans la pratique.
Le principe de responsabilité unique n'est pas une loi ou un mandat; c'est une ligne directrice ou un principe. La conception de logiciels est toujours une question de compromis; il n'y a pas d'absolu. Il n'est pas rare de compromis la lisibilité et / ou la maintenabilité pour la vitesse, vous devrez donc peut-être sacrifier SRP sur l'autel de la performance. Mais ne faites pas ce compromis sauf si vous savez que vous avez un problème de performances.
la source
Tout d'abord, quelques clarifications: Python est un langage. Il existe plusieurs interpréteurs différents qui peuvent exécuter du code écrit en langage Python. L'implémentation de référence (CPython) est généralement ce qui est référencé lorsque quelqu'un parle de "Python" comme s'il s'agissait d'une implémentation, mais il est important d'être précis lorsque l'on parle des caractéristiques de performances, car elles peuvent différer énormément entre les implémentations.
Cas 1.) Si vous avez du code Python pur (<= Python Language version 3.5, 3.6 a un "support de niveau bêta") qui ne repose que sur des modules Python purs, vous pouvez adopter SRP partout et utiliser PyPy pour l'exécuter. PyPy ( https://morepypy.blogspot.com/2019/03/pypy-v71-released-now-uses-utf-8.html ) est un interpréteur Python qui a un compilateur Just in Time (JIT) et peut supprimer la fonction appelez le temps système tant qu'il a suffisamment de temps pour "s'échauffer" en traçant le code exécuté (quelques secondes IIRC). **
Si vous êtes limité à utiliser l'interpréteur CPython, vous pouvez extraire les fonctions lentes dans des extensions écrites en C, qui seront précompilées et ne souffriront d'aucune surcharge d'interpréteur. Vous pouvez toujours utiliser SRP partout, mais votre code sera divisé entre Python et C. Que ce soit meilleur ou pire pour la maintenabilité que d'abandonner sélectivement SRP mais s'en tenir uniquement au code Python dépend de votre équipe, mais si vous avez des sections critiques de performances de votre , il sera sans aucun doute plus rapide que le code Python pur le plus optimisé interprété par CPython. Beaucoup des bibliothèques mathématiques les plus rapides de Python utilisent cette méthode (numpy et scipy IIRC). Ce qui est une belle transition vers le cas 2 ...
Cas 2.) Si vous avez du code Python qui utilise des extensions C (ou s'appuie sur des bibliothèques qui utilisent des extensions C), PyPy peut être utile ou non selon la façon dont il est écrit. Voir http://doc.pypy.org/en/latest/extending.html pour plus de détails, mais le résumé est que CFFI a une surcharge minimale tandis que CTypes est plus lent (son utilisation avec PyPy peut être encore plus lente que CPython)
Cython ( https://cython.org/ ) est une autre option avec laquelle je n'ai pas autant d'expérience. Je le mentionne par souci d'exhaustivité afin que ma réponse puisse "se suffire à elle-même", mais ne revendique aucune expertise. De mon utilisation limitée, j'ai eu l'impression de devoir travailler plus dur pour obtenir les mêmes améliorations de vitesse que je pouvais obtenir "gratuitement" avec PyPy, et si j'avais besoin de quelque chose de mieux que PyPy, il était tout aussi facile d'écrire ma propre extension C ( ce qui présente l'avantage si je réutilise le code ailleurs ou en extrait une partie dans une bibliothèque, tout mon code peut toujours être exécuté sous n'importe quel interpréteur Python et il n'est pas nécessaire qu'il soit exécuté par Cython).
J'ai peur d'être «enfermé» dans Cython, alors que tout code écrit pour PyPy peut également s'exécuter sous CPython.
** Quelques notes supplémentaires sur PyPy en production
Soyez très prudent lorsque vous faites des choix qui ont pour effet pratique de "vous enfermer" dans PyPy dans une grande base de code. Parce que certaines bibliothèques tierces (très populaires et utiles) ne fonctionnent pas bien pour les raisons mentionnées précédemment, cela peut entraîner des décisions très difficiles plus tard si vous réalisez que vous avez besoin de l'une de ces bibliothèques. Mon expérience consiste principalement à utiliser PyPy pour accélérer certains (mais pas tous) les microservices qui sont sensibles aux performances dans un environnement d'entreprise où il ajoute une complexité négligeable à notre environnement de production (nous avons déjà plusieurs langues déployées, certaines avec différentes versions majeures comme 2.7 vs 3.5 fonctionnant quand même).
J'ai trouvé que l'utilisation de PyPy et de CPython m'obligeait régulièrement à écrire du code qui ne repose que sur les garanties apportées par la spécification du langage lui-même, et non sur les détails d'implémentation qui sont susceptibles de changer à tout moment. Vous pouvez trouver la réflexion sur ces détails comme un fardeau supplémentaire, mais je l'ai trouvé précieux dans mon développement professionnel, et je pense que c'est "sain" pour l'écosystème Python dans son ensemble.
la source