J'ai téléchargé une version alpha de Python 3.6 depuis le dépôt Github de Python, et l'une de mes nouvelles fonctionnalités préférées est le formatage des chaînes littérales. Il peut être utilisé comme suit :
>>> x = 2
>>> f"x is {x}"
"x is 2"
Cela semble faire la même chose que d'utiliser la fonction format
sur une str
instance. Cependant, j'ai remarqué que ce formatage littéral de la chaîne de caractères est en fait très lent par rapport à un simple appel à la fonction format
. Voici ce que timeit
dit à propos de chaque méthode :
>>> x = 2
>>> timeit.timeit(lambda: f"X is {x}")
0.8658502227130764
>>> timeit.timeit(lambda: "X is {}".format(x))
0.5500578542015617
Si j'utilise une chaîne de caractères comme timeit
mais mes résultats montrent toujours le même schéma :
>>> timeit.timeit('x = 2; f"X is {x}"')
0.5786435347381484
>>> timeit.timeit('x = 2; "X is {}".format(x)')
0.4145195760771685
Comme vous pouvez le constater, l'utilisation de format
prend presque la moitié du temps. Je m'attendrais à ce que la méthode littérale soit plus rapide, car elle fait appel à moins de syntaxe. Que se passe-t-il en coulisses pour que la méthode littérale soit si lente ?
2 votes
Les chaînes f-strings sont dynamiques, de sorte que la chaîne doit être générée à chaque boucle, tandis que la chaîne format est un littéral créé avant l'exécution du code, lors de sa conversion en bytecode.
0 votes
@AlexHall Peut-être que cela a à voir avec le fait que
x
est assigné à une variable locale lorsqu'il est transmis à la fonctionformat
mais doit être trouvée dans la méthodeglobals
par lef"..."
la syntaxe.2 votes
@AlexHall : ce n'est pas un bug. Il y a simplement une implémentation différente sous le capot, car la chaîne de format doit être analysée au moment de la compilation, alors que l'implémentation de la chaîne de format n'a pas lieu.
str.format()
analyse les slots à temps de fonctionnement .1 votes
@PM2Ring : toutes les expressions sont compilées au moment de la compilation et évaluées au moment de l'exécution.
0 votes
@MartijnPieters si la chaîne est compilée au moment de l'exécution cela devrait signifier moins de calcul. Au minimum, si
.format
est plus rapide, alors ces chaînes devraient simplement être compilées en appels à.format
.0 votes
Remarquez que votre
.format
est la plus simple possible. Elle n'utilise même pas de kwargs, ni même d'accès indexé. Dès que vous utilisez'{x}'.format(x=x)
la différence a disparu.0 votes
@AnttiHaapala Même en utilisant cette méthode, les chaînes formatées littéralement sont toujours plus lentes, mais de moins en moins.