34 votes

Pourquoi est-ce que repr (int) est plus rapide que str (int)?

Je me demande pourquoi repr(int) plus rapide que de l' str(int). Avec l'extrait de code suivant:

ROUNDS = 10000

def concat_strings_str():
    return ''.join(map(str, range(ROUNDS)))

def concat_strings_repr():
    return ''.join(map(repr, range(ROUNDS)))

%timeit concat_strings_str()
%timeit concat_strings_repr()

Je reçois ces timings (python 3.5.2, mais des résultats très similaires avec 2.7.12):

 1.9 ms ± 17.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
 1.38 ms ± 9.07 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Si je suis sur la bonne voie, la même fonction long_to_decimal_string est appelé ci-dessous le capot.

Ai-je quelque chose de mal ou quoi d'autre qui se passe que je suis absent?


mise à jour: C'est probablement ce qui n'a rien à avec ints' __repr__ ou __str__ méthodes mais avec les différences entre repr() et str(), comme int.__str__ et int.__repr__ sont en fait comparable rapide:

def concat_strings_str():
    return ''.join([one.__str__() for one in range(ROUNDS)])

def concat_strings_repr():
    return ''.join([one.__repr__() for one in range(ROUNDS)])

%timeit concat_strings_str()
%timeit concat_strings_repr()

résultats:

2.02 ms ± 24.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.05 ms ± 7.07 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

33voto

Jim Points 8793

Parce que l'utilisation d' str(obj) doit d'abord passer par type.__call__ alors str.__new__ (créer une nouvelle chaîne) alors PyObject_Str (faire une chaîne de caractères de l'objet) qui invoque int.__str__ et, enfin, utilise la fonction que vous avez lié.

repr(obj), ce qui correspond à builtin_repr, appelle directement PyObject_Repr (obtenir l'objet repr) qui appelle int.__repr__ qui utilise la même fonction que int.__str__.

En outre, le chemin qu'ils empruntent dans call_function (la fonction qui gère l' CALL_FUNCTION opcode qui est générée pour les appels) est légèrement différent.

De la branche master sur GitHub (Disponible 3.7):

Comme la mise à jour des états, ce n'est pas sur int.__repr__ vs int.__str__, ils sont de la même fonction, après tout; il est tout au sujet de combien de repr et str les atteindre. str juste besoin de travailler un peu plus difficile.

12voto

aristotll Points 4102

Je viens de comparer les implémentations str et repr dans la branche 3.5. Voir ici

Il semble y avoir plus de contrôles en str : entrez la description de l'image ici

8voto

MSeifert Points 6307

Il y a plusieurs possibilités, car le Disponible les fonctions qui sont responsables de l' str et repr de retour sont légèrement différentes.

Mais je pense que la principale raison est qu' str est type (une classe) et l' str.__new__ méthode a appeler __str__ tout repr pouvez passer directement à la __repr__.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X