In sx.el
einem Fall müssen wir überprüfen, ob wir bestanden haben GET
oder POST
als Argument.
Derzeit wird das Argument als Zeichenfolge übergeben und (string= "GET" url-method)
zum Vergleichen verwendet "GET"
.
Gibt es einen Vorteil der Elisp / Byte-Kompilierung, wenn Sie es in ein Symbol ändern (equal url-method 'GET)
?
elisp
byte-compilation
Jonathan Leech-Pepin
quelle
quelle
eq
mit einem Symbol zu vergleichen.eq
konvertiert Emacs-Objekte inint
und vergleicht sie. Der Vergleich vonint
s ist viel schneller als der Vergleich vonstring
s.string=
funktioniert wie erwartet, unabhängig davon, oburl-method
es sich um ein Symbol oder eine Zeichenfolge handelt. OTOH Wenn Sieeq
oder verwendenequal
, müssen Sie sicherstellen, dass die Argumente vom gleichen Typ sind.Antworten:
Neue Benutzer von Lisp, die aus anderen Sprachen stammen, verwenden manchmal aus Gewohnheit Zeichenfolgen für solche Zwecke.
Symbole können mit
eq
statt nur verglichen werdenequal
.string=
verwendet Code ähnlich wieequal
, um jedes Zeichen zu testen, bis eine Nichtübereinstimmung gefunden wird. Der Symbolvergleich kann also etwas schneller sein. Wenn Sie den Vergleich beispielsweise in einer Schleife verwenden, kann der Unterschied von Bedeutung sein.Abhängig vom jeweiligen Code kann es außerdem häufig einfacher oder lesbarer sein, Symbole anstelle von Zeichenfolgen zu verwenden. Und es gibt Funktionen (und Makros usw.), die Symbole erwarten oder die Dinge standardmäßig mit
eq
(odereql
) vergleichen . Um diese mit Zeichenfolgen zu verwenden, müssen Sie ohnehin in Symbole konvertieren.quelle
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
schenktstring=
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 dasquote
für den Großteil des Geschwindigkeitsunterschieds verantwortlich war:ist für kleinere Saiten durchweg schneller als:
Wenn wir jedoch auch die Zeichenfolge zitieren:
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:
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 alsstring=
(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.
quelle
intern
+eq
gegenstring=
. Oder möglicherweise aus einem ganz anderen Grund: Es ist unmöglich zu sagen, ohne Ihren Code zu sehen. Sie sollten Ihren Testcode als Frage auf dieser Site veröffentlichen.benchmark-run-compiled
(mit der Idee, dass das die Kosten von entfernen würdeintern
), aber mehrmals negative Ergebniszeiten erhalten. Ich denke, beide Operationen sind zu schnell, um zuverlässig zu messen.