Vergleichen der Geschwindigkeit von startswith () .vs. als Duplikat]

8

Ich hatte den Eindruck, dass startswith schneller sein muss als in , und zwar aus dem einfachen Grund, dass in mehr Prüfungen durchführen muss (erlaubt das gesuchte Wort) für irgendwo in der Zeichenfolge sein) . Aber ich hatte meine Zweifel, also entschied ich mich für timeit . Der Code für die Timings ist unten angegeben und wie Sie wahrscheinlich bemerken werden, habe ich nicht viel Timing gemacht; Der Code ist ziemlich einfach.

%Vor%

Ergebnisse:

%Vor%

Also startswith ist doppelt so langsam! .. Ich finde dieses Verhalten sehr verwirrend angesichts dessen, was ich weiter oben gesagt habe. Mache ich etwas falsch mit dem Timing der beiden oder ist in tatsächlich schneller? Wenn ja, warum?

Beachten Sie, dass die Ergebnisse sehr ähnlich sind, auch wenn beide False zurückgeben (in diesem Fall müsste in tatsächlich den gesamten Sentece durchqueren, falls es zuvor einfach kurzgeschlossen wurde ) :

%Vor%

Wenn ich die beiden Funktionen von Grund auf implementieren müsste, würde das in etwa so aussehen (Pseudocode):

startswith : Beginnen Sie, die Buchstaben von Wort nacheinander mit den Buchstaben von Satz zu vergleichen, bis ein Wort leer ist (return) True) oder b) check gibt False zurück (return False)

in : Rufen Sie startswith für jede Position auf, in der der Anfangsbuchstabe von Wort in Satz enthalten ist.

Ich verstehe es einfach nicht ..

Nur um es deutlich zu machen: in und startswith sind nicht gleichwertig ; Ich spreche gerade über den Fall, in dem das Wort, das man finden will, das erste in einer Zeichenkette sein muss.

    
Ev. Kounis 13.06.2017, 11:25
quelle

3 Antworten

8

Dies liegt daran, dass Sie eine Methode suchen und aufrufen müssen. in ist spezialisiert und führt direkt zu COMPARE_OP (Aufruf cmp_outcome der wiederum PySequence_Contains aufruft, während str.startswith den langsameren Byte-Code durchläuft:

%Vor%

Das Ersetzen von in durch __contains__ und das Erzwingen eines Funktionsaufrufs für diesen Fall macht die Geschwindigkeitsdifferenz nahezu ungültig:

%Vor%

Und die Zeiten:

%Vor%

in gewinnt hier wegen der Tatsache, dass es nicht den gesamten Funktionsaufrufaufbau durchlaufen muss und wegen des günstigen Falles, den es präsentiert.

    
Jim Fasarakis Hilliard 13.06.2017, 11:38
quelle
5

Sie vergleichen einen Operator für Strings -vs-, eine Attributsuche und einen Funktionsaufruf. Der zweite wird einen höheren Overhead haben, selbst wenn der erste eine lange Zeit für eine Menge Daten braucht.

Zusätzlich suchen Sie nach dem ersten Wort. Wenn es also passt, wird in genauso viele Daten betrachten wie startswith() . Um den Unterschied zu sehen, sollten Sie einen pessimistischen Fall betrachten (keine Ergebnisse gefunden oder am Ende der Zeichenfolge gefunden):

%Vor%     
viraptor 13.06.2017 11:39
quelle
0

Wenn Sie sich den von Ihren Funktionen erzeugten Bytecode ansehen:

%Vor%

Sie werden feststellen, dass viel Overhead nicht direkt mit dem String-Matching zusammenhängt. Den Test für eine einfachere Funktion durchführen:

%Vor%

wird zuverlässiger sein.

    
Błotosmętek 13.06.2017 11:49
quelle