Étonnamment, je trouve startswith
plus lente que l' in
:
In [10]: s="ABCD"*10
In [11]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 307 ns per loop
In [12]: %timeit "XYZ" in s
10000000 loops, best of 3: 81.7 ns per loop
Comme nous le savons tous, l' in
besoins de l'opération de recherche de l'ensemble de la chaîne et de l' startswith
juste besoin de vérifier les premiers caractères, startswith
devrait être plus efficace.
Lors de l' s
est assez grand, startswith
est plus rapide:
In [13]: s="ABCD"*200
In [14]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 306 ns per loop
In [15]: %timeit "XYZ" in s
1000000 loops, best of 3: 666 ns per loop
Il semble donc que l'appelant startswith
a une surcharge, ce qui le rend plus lent lorsque la chaîne est faible.
Et que j'ai essayé de comprendre ce qu'est la surcharge de l' startswith
appel.
Tout d'abord, j'ai utilisé un f
variable pour réduire le coût de la dot de l'opération - comme indiqué dans cette réponse - là, on peut voir startswith
est encore plus lent:
In [16]: f=s.startswith
In [17]: %timeit f("XYZ")
1000000 loops, best of 3: 270 ns per loop
De plus, j'ai testé le coût d'un vide appel de la fonction:
In [18]: def func(a): pass
In [19]: %timeit func("XYZ")
10000000 loops, best of 3: 106 ns per loop
Quel que soit le coût de la dot de fonctionnement et d'appel de fonction, le temps d' startswith
(270-106)=164ns, mais l' in
opération ne prend que de 81,7 ns. Il semble qu'il y a encore quelques frais pour startswith
, c'est quoi?
Ajouter le résultat du test entre startswith
et __contains__
comme suggéré par poke et lvc:
In [28]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 314 ns per loop
In [29]: %timeit s.__contains__("XYZ")
1000000 loops, best of 3: 192 ns per loop