Warum ist startswith langsamer als slicing

Warum ist die Umsetzung von startwith langsamer als schneiden?

In [1]: x = 'foobar'

In [2]: y = 'foo'

In [3]: %timeit x.startswith(y)
1000000 loops, best of 3: 321 ns per loop

In [4]: %timeit x[:3] == y
10000000 loops, best of 3: 164 ns per loop

Überraschend, sogar einschließlich der Berechnung für die Länge, schneiden, scheint immer noch deutlich schneller:

In [5]: %timeit x[:len(y)] == y
1000000 loops, best of 3: 251 ns per loop

Hinweis: der erste Teil dieses Verhaltens wird darauf hingewiesen, in Python for Data Analysis (Kapitel 3), aber keine Erklärung dafür angeboten wird.

.

Falls hilfreich: hier ist der C-code für startswith; und hier ist die Ausgabe von dis.dis:

In [6]: import dis

In [7]: dis_it = lambda x: dis.dis(compile(x, '<none>', 'eval'))

In [8]: dis_it('x[:3]==y')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (3)
              6 SLICE+2             
              7 LOAD_NAME                1 (y)
             10 COMPARE_OP               2 (==)
             13 RETURN_VALUE        

In [9]: dis_it('x.startswith(y)')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_ATTR                1 (startswith)
              6 LOAD_NAME                2 (y)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE 
  • Schneiden ist wahrscheinlich optimiert, stärker auf C-Ebene
  • dies entspricht nicht dem code. können Sie ein Tupel zu startswith können Sie start und end Parameter, die Pflege und das kostet Zeit.
  • Wenn Sie sprechen über die Optimierung der zugrunde liegenden Betriebssystems und die Architektur der CPU sind sehr wichtig. Ist das eine x86 - (Intel oder AMD) oder x86-64bit? oder ein ARM-core, windows oder linux...?
  • Dies ist ein Intel x86-64-unter osx. Ich hatte gedacht, dass (weitgehend) C (und damit CPython) - Implementierungen auf allen Plattformen vergleichbar wäre (D. H. wenn man Architektur läuft der code langsamer, dann werden es auch andere)...?
  • Unterschiede version von OS-standard-Bibliotheken, die version des Compilers verwendet, die Menge des verfügbaren Speichers wenn Sie den test ausführen, die hintergrund-tasks/Prozesse laufen, ob der Prozessor von Intel oder AMD, etc etc können ALLE verursachen Variationen in der benchmark-Ergebnisse. Vor allem, wenn Sie ' re Umgang mit einem wiederholten test (wobei die Werte sind die gleichen-und Nanosekunden-Messungen werden verglichen. Sie könnte knapp werden in Zwischenspeichern und branch prediction Optimierungen auf der Architektur-Ebene könnte verzerren die Ergebnisse.
  • Ich bin damit einverstanden, die zahlen selbst werden verschiedene (wenn ich Sie laufen zweimal, Sie sind anders!), aber ich wäre überrascht, wenn erhebliche Unterschiede (D. H. eine schneller als der andere) wurden nicht reflektiert, die auf allen Plattformen aufgrund der Laufzeit der C-compiler. Ich hatte nicht darüber nachgedacht "Cache-und branch predictions" auf einer Architektur-Ebene... interessant.

InformationsquelleAutor Andy Hayden | 2012-11-07
Schreibe einen Kommentar