1
votes

Rendre Python plus compact le rend-il plus efficace?

En ignorant la lisibilité du code, vaut-il la peine de supprimer les variables redondantes?

Par exemple. conversion de ce code:

name = "{:>3}-{:0>5.2f}".format(
    milisec // (1000 * 60), # minutes
    (milisec / 1000) % 60,  # seconds
    )

en:

seconds = (milisec / 1000) % 60
minutes = milisec // (1000 * 60)
name = "{:>3}-{:0>5.2f}".format(minutes, seconds)


7 commentaires

Je ne vois pratiquement aucune différence dans les deux approches. L'approche 1 est juste un peu plus propre et c'est vraiment ça,


"Ignorer la lisibilité du code" - Ou, et écoutez-moi, pourquoi ne pas faire ça?


assigner à une variable est une instruction de bytecode, et la référencer en est une autre ... donc une différence très marginale, pratiquement non pertinente. Dans ce genre de code? Sans aucun doute cela ne vaut pas la peine. Si vous effectuez une micro-optimisation à ce niveau, CPython est probablement le mauvais outil.


Remarquez que le premier formulaire ne nécessitait pas de commentaires pour vous dire ce qu'il faisait? C'est le signe d'un meilleur code.


Optez pour votre première option - mais pour les deux options, si milisec est censé être un nombre de millisecondes, il devrait probablement être millisec . À moins que ce code ne soit exécuté des milliards de fois, je suis sûr qu'il y a des choses plus importantes à se soucier dans la conception et la mise en œuvre de votre solution.


Que signifie efficace python? Temps d'exécution? Utilisation de la mémoire? Utilisation de la pile? Compréhensibilité du programmeur (donc efficacité du temps de développement)? Consommation du registre du processeur?


L'optimisation prématurée est la racine de tous les maux . Faites ce que vous jugez le plus naturel et le plus lisible, et optimisez-le si cela devient un goulot d'étranglement en termes de performances.


3 Réponses :


0
votes

La création de variables prend un peu de place en mémoire, donc ce serait plus rapide si vous ne le faites pas. Cependant, c'est une très petite différence.


1 commentaires

Il doit y avoir une énorme étiquette avec des néons clignotants disant que si la création et l'instanciation d'une variable sont, à proprement parler, moins performantes qu'une option qui ne le fait pas, la différence est entièrement négligeable au point d'être bien à l'intérieur. la marge d'erreur sur pratiquement n'importe quel système de benchmarking et ne vaut même pas la peine d'être prise en compte sur tous les besoins, sauf les plus exigeants en termes d'efficacité de vitesse / mémoire.



-1
votes

Oui, votre deuxième morceau de code, comme vous dites plus compact, sera légèrement plus efficace car l'affectation de variables correspond à certaines instructions de la machine.

from timeit import timeit

def function():

    milisec = 173000

    seconds = (milisec / 1000) % 60
    minutes = milisec // (1000 * 60)
    name = "{:>3}-{:0>5.2f}".format(minutes, seconds)


print(timeit(stmt='function()', setup='from __main__ import function', ))



def function2():
    milisec = 173000
    name = "{:>3}-{:0>5.2f}".format(
    milisec // (1000 * 60), # minutes
    (milisec / 1000) % 60,  # seconds
    )

print(timeit(stmt='function2()', setup='from __main__ import function2', ))

voir une différence sur une exécution de lots (en secondes)

 entrez la description de l'image ici


5 commentaires

Ce benchmark ne teste pas seulement les parties pertinentes du code (par exemple, milisec = 173000 n'a rien à voir avec le code testé et doit être retiré) et n'inclut pas d'autres informations pertinentes pour le benchmark pour que les résultats soient significatifs. Par exemple, combien d'itérations de chaque fonction ont été exécutées? Quel est le temps d'exécution moyen et l'écart type de chaque itération? Combien de fois le benchmark a-t-il été exécuté?


Et pour répondre à votre question, vous pourriez penser qu'instancier la variable dans les deux tests serait égal, mais ce que vous testez est une différence opérationnelle de l'ordre de milliardièmes de seconde ou moins. En supposant que vous puissiez même trouver une différence pratique à cette échelle, cela vous oblige à éliminer autant d'opérations superflues que possible de votre benchmark. Les points de données arbitraires sont du bruit et le bruit déforme les résultats, puis lorsque vos données réelles ont la même magnitude que votre bruit, vous vous retrouvez sans aucune donnée utilisable. Vous n'avez pas besoin d'un "doctorat" pour comprendre les statistiques de base, mec.


Vous avez publié vos résultats et j'ai dit que le manque de transparence et de rigueur dans la façon dont vous avez produit et présenté ces résultats rendait votre conclusion trompeuse et peu fiable. Vous auriez pu facilement modifier votre code et inclure les informations pertinentes (que timeit fournit par défaut) et cela aurait résolu tous les problèmes. Au lieu de cela, vous décidez d'argumenter à ce sujet et de prétendre que je vous «dénigre». StackOverflow existe pour fournir des réponses de qualité. Votre réponse n'est pas de très bonne qualité, et je vous ai expliqué précisément pourquoi. Pourquoi prenez-vous cela si personnellement?


En d'autres termes, comparez votre réponse à la première réponse. Ils ont utilisé exactement la même approche que vous, mais ils n'ont testé que le code qui devait être testé et ont présenté leurs résultats de manière très transparente et professionnelle. La quantité d'efforts qu'il vous faudrait pour que la qualité de votre réponse corresponde à la leur est minuscule. C'est une chose incroyablement idiote à prendre en charge.


Oui, tu as raison. J'accepte que vous commentiez et corrigiez ma réponse si vous trouvez qu'elle manque de rigueur. Je viens de trouver votre réaction un peu disproportionnée, mais ce n'est qu'une interprétation personnelle. Fermons-le ici. Il vaut toujours mieux faire toujours plus et plus précisément que faire moins.



1
votes

En terme de temps d'exécution, le code compact est légèrement plus rapide que le code long . Une évaluation rapide pourrait être la suivante:

 entrez la description de l'image ici

Cela étant dit, la lisibilité du code compte . C'est l'un des jalons du code Python. Le débogage, la maintenance, le travail en équipe (pour n'en nommer que quelques-uns) profitent d'une meilleure lisibilité du code.


1 commentaires

Il convient de noter que, même après 10 millions d'itérations, les deux approches fonctionnent dans ou très près de l'écart type l'une de l'autre, ce qui signifie que celle qui opère le plus rapidement pourrait très bien dépendre d'autres aspects qui échappent au contrôle du programmeur. Même en ignorant cela, la différence entre les opérations est de l'ordre de une demi-nanoseconde. C'est la définition même d'une micro-optimisation qui ne devrait _ jamais_ être prioritaire sur la lisibilité du code .