TL;DR - QUESTION 21118
L'Histoire
Josh Rosenberg a découvert que l' str.translate()
fonction est très lente par rapport à l' bytes.translate
, il a soulevé une question, en déclarant que:
En Python 3, str.translate()
est généralement un rendement pessimization, pas d'optimisation.
Pourquoi était - str.translate()
- il lent?
La raison principale pour str.translate()
très lent a été que la recherche dans un dictionnaire Python.
L'utilisation de l' maketrans
fait de ce problème pour le pire. La même approche à l'aide de bytes
construit un C tableau de 256 éléments de rapide de la table de recherche. Donc l'utilisation de plus haut niveau Python dict
fait l' str.translate()
en Python 3.4 très lent.
Ce qui s'est passé maintenant?
La première approche a été d'ajouter un petit patch, translate_writer, Cependant, l'augmentation de la vitesse n'était pas agréable. Bientôt un autre patch fast_translate a été testé et il a donné de très bons résultats jusqu'à 55% plus rapide.
Le principal changement que peut être vu à partir du fichier, c'est que le Python recherche dans le dictionnaire est changé en un C niveau de la recherche.
Les vitesses de maintenant sont presque les mêmes que bytes
unpatched patched
str.translate 4.55125927699919 0.7898181750006188
str.translate from bytes trans 1.8910855210015143 0.779950579000797
Une petite note ici, c'est que l'amélioration de la performance est seulement important dans les chaînes ASCII.
Comme J. F. Sebastian mentionne dans un commentaire ci-dessous, Avant de 3.5, traduire l'habitude de travailler de la même façon pour les deux ASCII et non-ASCII cas. Cependant, à partir de 3,5 ASCII cas est beaucoup plus rapide.
Plus tôt ASCII vs non-ascii utilisé pour être presque la même, mais maintenant, nous pouvons voir un grand changement dans la performance.
Il peut être une amélioration de 71.6 µs à 2,33 µs, comme on le voit dans cette réponse.
Le code suivant illustre cette
python3.5 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
100000 loops, best of 3: 2.3 usec per loop
python3.5 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 117 usec per loop
python3 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 91.2 usec per loop
python3 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
10000 loops, best of 3: 101 usec per loop
Dépouillement des résultats:
Python 3.4 Python 3.5
Ascii 91.2 2.3
Unicode 101 117