Warum startet der String langsamer als in?
berraschenderweise finde ichstartswith
ist langsamer alsin
:
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
ie wir alle wissen, diein
Operation muss den gesamten String durchsuchen undstartswith
muss nur die ersten Zeichen prüfen, alsostartswith
sollte effizienter sein.
Wanns
ist groß genug,startswith
ist schneller
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
So scheint es, dass das Aufrufen vonstartswith
hat etwas Overhead, was es langsamer macht, wenn der String klein ist.
Und dann habe ich versucht herauszufinden, was der Aufwand für das @ istartswith
Anruf
Zunächst habe ich ein @ verwendf
-Variable, um die Kosten der Punktoperation zu senken - wie in diesem @ erwähAntworte - hier können wir @ sehstartswith
ist noch langsamer:
In [16]: f=s.startswith
In [17]: %timeit f("XYZ")
1000000 loops, best of 3: 270 ns per loop
Ferner habe ich die Kosten eines leeren Funktionsaufrufs getestet:
In [18]: def func(a): pass
In [19]: %timeit func("XYZ")
10000000 loops, best of 3: 106 ns per loop
nabhängig von den Kosten der Punktoperation und des Funktionsaufrufs ist die Zeit vonstartswith
ist ungefähr (270-106) = 164ns, aber dasin
ie @ -Operation dauert nur 81,7 ns. Es scheint, dass es noch einige Gemeinkosten für @ gistartswith
, was ist das
Hinzufügen des Testergebnisses zwischenstartswith
und__contains__
wie von poke und lvc vorgeschlagen:
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