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 dasinie @ -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