Je passe par un lien sur les générateurs que quelqu'un a affiché. Au début, il compare les deux fonctions ci-dessous. Lors de sa configuration, il a montré une augmentation de vitesse de 5% avec le générateur.
Je couronne Windows XP, Python 3.1.1 et ne peut sembler dupliquer les résultats. Je continue à montrer la "vieille façon" (LOGS1) comme étant légèrement plus rapide lorsqu'il est testé avec les journaux fournis et jusqu'à 1 Go de données dupliquées. P>
Quelqu'un peut-il m'aider à comprendre ce qui se passe différemment? p>
Merci! P>
def logs1():
wwwlog = open("big-access-log")
total = 0
for line in wwwlog:
bytestr = line.rsplit(None,1)[1]
if bytestr != '-':
total += int(bytestr)
return total
def logs2():
wwwlog = open("big-access-log")
bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog)
getbytes = (int(x) for x in bytecolumn if x != '-')
return sum(getbytes)
3 Réponses :
Vous n'avez pas de réponse après presque une demi-heure. Je pose quelque chose qui a du sens pour moi, pas nécessairement la bonne réponse. Je pense que c'est mieux que rien après presque une demi-heure: P>
Le premier algorithme utilise un générateur. Fonctions de générateur en chargeant le premier page des résultats de la liste (en mémoire ) et charte continuellement les pages successives (en mémoire) jusqu'à ce qu'il ne reste plus rien à lire à partir de l'entrée. P>
Le deuxième algorithme utilise deux générateurs, chacun avec une instruction code> si code> pour un total de deux comparaisons par boucle par opposition à la première comparaison d'une algorithme. P>
La deuxième algorithme appelle également la fonction En tant que tel, pour des entrées suffisamment grandes, le deuxième algorithme a plus de comparaisons et un appel de fonction supplémentaire que le premier. Cela pourrait éventuellement expliquer pourquoi il faut plus de temps que le premier algorithme. P>
J'espère que cela aide p> somme code> à la fin par opposition à la première algorithme qui conserve simplement l'ajout d'entiers pertinents car il continue à les rencontrer. P>
"De plus, le deuxième algorithme appelle la fonction somme à la fin par opposition au premier algorithme qui conserve simplement l'ajout d'entiers pertinents, car il continue à les rencontrer." Je pense i> Cela ne ferait aucune différence car la somme () ne met probablement pas toutes les valeurs en mémoire, puis les ajoutent. Cela les ajoute probablement comme il itère, tout comme l'autre code.
Dans les diapositives de David Beazley que vous avez liées à, il déclare que tous les tests ont été exécutés avec "Python 2.5.1 sur OS X 10.4.11" et vous dites que vous exécutez des tests avec Python 3.1 sur Windows XP. Donc, réalisez que vous faites des pommes à la comparaison des oranges. Je soupçonne des deux variables, la version Python compte beaucoup plus. P>
Python 3 est une bête différente que Python 2. Beaucoup de choses ont changé sous la hotte (même dans la branche Python 2). Cela inclut les optimisations de performance ainsi que les régressions de performance (voir, par exemple, Poste de blog récent de Beazley sur les E / S à Python 3 ). Pour cette raison, le Conseils de performance Python Page Explicitement, P>
Vous devez toujours tester ces conseils avec votre application et la version de Python que vous avez l'intention d'utiliser et non seulement accepter aveuglément qu'une méthode est plus rapide qu'un autre. p> blockQuote>
Je devrais mentionner qu'une zone que vous pouvez compter sur les générateurs aidant est de réduire la consommation la mémoire em>, plutôt que la consommation de la CPU. Si vous avez une grande quantité de données dans lesquelles vous calculez ou extrayez quelque chose de chaque pièce individuelle et que vous n'avez pas besoin des données après, les générateurs vont briller. Voir compréhension génératrice pour plus de détails. P>
Compris, je soupçonnais tout ce qui est pourquoi j'ai posté que j'utilisais Python3. Encore une fois, j'étais curieux ce qui se passe différemment.
Si vous êtes vraiment curieux, essayez d'exécuter les tests de timing avec une installation Python 2.6; Si cela ne vous donne pas une différence, essayez avec un Python 2.5 Installez et voyez si vous ne pouvez toujours pas reproduire les résultats de Beazley. Ou vous pouvez être paresseux comme moi et juste mail Python-Dev.
Pour ce que cela vaut, l'objectif principal de la comparaison de la vitesse dans la présentation était de souligner que l'utilisation de générateurs n'introduit pas une augmentation de la performance énorme. De nombreux programmeurs, lors de la première vue des générateurs, pourraient commencer à s'interroger sur les coûts cachés. Par exemple, y a-t-il toutes sortes de magie de fantaisie dans les coulisses? Utilise cette fonctionnalité va faire fonctionner mon programme deux fois plus lent? P>
En général ce n'est pas le cas. L'exemple est censé montrer qu'une solution de générateur peut fonctionner essentiellement à la même vitesse, sinon légèrement plus rapide dans certains cas (bien que cela dépend de la situation, de la version de Python, etc.). Si vous observez d'énormes différences de performance entre les deux versions, ce serait alors quelque chose d'intéressant d'enquêter. P>
Cela me semble que ces deux fonctions sont essentiellement les mêmes. Dans aucun cas, vous construisez une énorme liste, lorsque vous auriez pu utiliser un générateur à la place. Donc, je ne suis pas surpris qu'ils courent à peu près la même vitesse.
Cela a du sens, je suis juste curieux pourquoi il a obtenu une augmentation de 5% de vitesse et je vois une diminution de 1% de manière systématique.