Beachten Sie, dass der Lisp-Reader Symbole interniert , sodass unabhängige Verweise auf ein bestimmtes Symbol genau dasselbe Lisp-Objekt ergeben und Sie sie folglich vergleichen können eq
(wobei nur die Objektadressen verglichen werden müssen).
Umgekehrt sind unabhängige Zeichenfolgen immer unterschiedliche Lisp-Objekte , und daher müssen Sie deren Inhalt vergleichen.
Sie würden daher erwarten, dass der eq
Vergleich für die Leistung gewinnt.
Merkwürdigerweise (ich bin auf jeden Fall sehr überrascht), einige triviale Tests mit benchmark-run
schenkt string=
den Sieg durch eine ganze Marge. Das kommt mir sehr merkwürdig vor. YMMV?
Bearbeiten: Also habe ich diese Antwort (und ihren Kommentar) gerade wieder bemerkt und mich inspiriert gefühlt, um zu sehen, ob ich das Ergebnis neu erstellen und erklären kann.
nb Zunächst wird nichts bytekompiliert.
Die erste Erkenntnis war, dass meine Symbole quote
d waren und die Zeichenfolgen nicht, und ich stellte sofort fest, dass das quote
für den Großteil des Geschwindigkeitsunterschieds verantwortlich war:
(benchmark-run 10000000
(string= "foo" "foo"))
ist für kleinere Saiten durchweg schneller als:
(benchmark-run 10000000
(eq 'foo 'foo))
Wenn wir jedoch auch die Zeichenfolge zitieren:
(benchmark-run 10000000
(string= '"foo" '"foo"))
das gleicht die Dinge fast vollständig aus.
Im Durchschnitt scheint der Saitenvergleich jedoch immer noch um ein Haar zu gewinnen , es sei denn, die Saite ist ziemlich groß .
Ein alternativer Ansatz besteht darin, die Objekte an Variablen zu binden:
(let ((foo 'test)
(bar 'test))
(benchmark-run 10000000
(eq foo bar)))
(let ((foo "test")
(bar "test"))
(benchmark-run 10000000
(string= foo bar)))
Wieder sehe ich den Saitenvergleich im Durchschnitt schneller durch eine Nase.
Nach der Byte-Kompilierung sehe ich nur ein konsistentes Ergebnis für die let-gebundenen Variablenfälle, bei denen eq
es konsistent schneller ist als string=
(ungefähr 2/3 der Zeit).
Bei den anderen Beispielen erhalte ich (für mich) unsinnige Ergebnisse, da die zitierten Zeichenfolgen schneller sind als die nicht zitierten Zeichenfolgen, was ich nur vermuten kann, ist effektiv Rauschen von anderen Aspekten der Ausführung und / oder von sich benchmark-run
selbst. Es gab genug Abwechslung zwischen verschiedenen Läufen derselben Funktion, um Unterschiede zwischen Läufen verschiedener Funktionen vollständig zu verschleiern.
Meine Schlussfolgerungen sind:
(a) eq
Vergleiche mit einem Symbol können (etwas kontraintuitiv) langsamer sein als ein Zeichenfolgenvergleich, wenn das Symbol in Anführungszeichen steht.
(b) Wenn die Saiten nicht ziemlich groß sind, sind die praktischen Unterschiede völlig vernachlässigbar, und deshalb würde ich mich aus rein leistungsbezogenen Gründen nicht darum kümmern, eine in die andere umzuwandeln.
eq
mit einem Symbol zu vergleichen.