Ce n'backticks moyenne de l'interpréteur python: `num`
Je suis en train de jouer autour avec des interprétations de la liste et je suis tombé sur ce petit extrait de code sur un autre site:
return ''.join([`num` for num in xrange(loop_count)])
J'ai passé quelques minutes à essayer de reproduire la fonction (en tapant) avant de réaliser la `num`
peu cassât.
Ce n'joignant une déclaration dans ces personnages n'? De ce que je peux voir c'est l'équivalent de str(num). Mais quand je l'ai chronométré:
return ''.join([str(num) for num in xrange(10000000)])
Il faut 4.09 s tandis que:
return ''.join([`num` for num in xrange(10000000)])
prend 2.43 s.
Les deux donnent des résultats identiques, mais l'un est beaucoup plus lent. Ce qui se passe ici?
EDIT: Bizarrement... repr()
donne un peu plus lent, les résultats que `num`
. 2.99 s vs 2.43 s. À l'aide de Python 2.6 (n'ai pas essayé encore 3.0).
- Après la lecture de la "un autre du site" dans le skymind.com/~ocrow/python_string, j'ai eu une question similaire, et trouvé cette page. Bonne question et la réponse belle 🙂
InformationsquelleAutor Dominic Bou-Samra | 2009-11-04
Vous devez vous connecter pour publier un commentaire.
Backticks sont obsolète, alias pour
repr()
. Ne les utilisez pas plus, la syntaxe a été supprimé en Python 3.0.À l'aide de backticks semble être plus rapide que l'utilisation
repr(num)
ounum.__repr__()
dans la version 2.x. Je suppose que c'est parce que plus de recherche dans le dictionnaire est nécessaire dans l'espace de noms global (pourrepr
), ou dans l'objet de l'espace de noms (pour__repr__
), respectivement.À l'aide de la
dis
module prouve mon hypothèse:Démontage montre:
f1
implique un mondial de recherche pourrepr
,f2
un attribut de recherche pour__repr__
, alors que le backtick opérateur est mis en œuvre dans un autre opcode. Depuis il n'y a pas de frais généraux pour la recherche dans le dictionnaire (LOAD_GLOBAL
/LOAD_ATTR
), ni pour les appels de fonction (CALL_FUNCTION
), backticks sont plus rapides.Je suppose que le Python personnes ont décidé qu'ayant un faible niveau de fonctionnement pour
repr()
n'est pas la peine, et que les deuxrepr()
et backticks, viole le principe dede sorte que la fonctionnalité a été supprimée en Python 3.0.
there is no overhead for dictionary lookup nor for function calls
est vrai?dis
, il montre comment Python implémente les fonctions en interne.LOAD_GLOBAL
signifie qu'il y a une recherche dans le dictionnaire, au niveau mondial, pour la fonctionrepr
, qui est appelée par la suite.LOAD_ATTR
est une recherche dans le dictionnaire pour l'attribut__repr__
qui est aussi appelé. Les deux n'est pas nécessaire pour les backticks version, où il existe un opcodeUNARY_CONVERT
sansLOAD_*
etCALL_FUNCTION
. Donc le code qui fait ce querepr()
n'est atteint plus directement, et l'ensemble de la fonction effectue mieux.Backtick échappement n'est généralement pas utile et disparu en Python 3.
Pour ce que ça vaut, c':
est légèrement plus rapide que la backtick version pour moi. Mais se soucier de ce qui est probablement prématuré de l'optimisation.
timeit
les rendements des résultats plus rapides pour''.join(map(repr, xrange(0, 1000000)))
que pour''.join([repr(i) for i in xrange(0, 1000000)])
(encore pire pour''.join( (repr(i) for i in xrange(0, 1000000)) )
). C'est un peu décevant 😉map
est implémenté en C, à l'aide d'une boucle C, qui est beaucoup plus rapide qu'une boucle Python exécuté dans la machine virtuelle.map
semble parfaitement clair et concis pour moi, et je ne sais même pas Python.map
est parfaitement clair, mais je ne l'utiliserais une compréhension dans la pratique, parce que ce n'est pas la peine de cognement d'autres développeurs. Certaines choses valent la peine de la friction, ce n'est pas le cas.map
.Ma conjecture est que
num
ne définit pas la méthode__str__()
, doncstr()
a le faire une deuxième recherche pour__repr__
.Les backticks regarder directement pour
__repr__
. Si cela est vrai, alors l'utilisation derepr()
au lieu de les backticks devrait vous donner les mêmes résultats.