Wissen Sie, ob die Verwendung von doppelten Anführungszeichen anstelle von einfachen Anführungszeichen in Ruby die Leistung in Ruby 1.8 und 1.9 auf sinnvolle Weise verringert?
also wenn ich tippe
question = 'my question'
ist es schneller als
question = "my question"
Ich stelle mir vor, dass Ruby versucht herauszufinden, ob etwas bewertet werden muss, wenn es auf doppelte Anführungszeichen stößt, und wahrscheinlich einige Zyklen damit verbringt, genau das zu tun.
ruby
performance
syntax
dimus
quelle
quelle
Antworten:
Hinweis: Ich habe dies aktualisiert, damit es mit neueren Ruby-Versionen funktioniert, den Header bereinigt und den Benchmark auf einem schnelleren System ausgeführt.
Diese Antwort lässt einige wichtige Punkte aus. Siehe insbesondere diese anderen Antworten zur Interpolation und den Grund, warum es keinen signifikanten Leistungsunterschied gibt, wenn einfache oder doppelte Anführungszeichen verwendet werden.
quelle
'
und,"
da sie auf dasselbe analysiert werden.Zusammenfassung: kein Geschwindigkeitsunterschied; In diesem großartigen kollaborativen Ruby-Styleguide wird empfohlen, konsistent zu sein. Ich verwende
'string'
es jetzt, sofern keine Interpolation erforderlich ist (Option A in der Anleitung) und es gefällt mir, aber Sie werden normalerweise mehr Code mit sehen"string"
.Einzelheiten:
Theoretisch kann es einen Unterschied machen, wenn Ihr Code analysiert wird. Wenn Sie sich jedoch nicht nur nicht um die Analysezeit im Allgemeinen kümmern (im Vergleich zur Ausführungszeit vernachlässigbar), können Sie in diesem Fall keinen signifikanten Unterschied feststellen.
Wichtig ist, dass es genau gleich ist, wenn es ausgeführt wird .
Das Benchmarking zeigt nur einen Mangel an Verständnis dafür, wie Ruby funktioniert. In beiden Fällen werden die Zeichenfolgen auf a analysiert
tSTRING_CONTENT
(siehe Quelle inparse.y
). Mit anderen Worten, die CPU durchläuft beim Erstellen von'string'
oder genau dieselben Vorgänge"string"
. Die exakt gleichen Bits werden genauso gespiegelt. Beim Benchmarking werden nur Unterschiede angezeigt, die nicht signifikant sind und auf andere Faktoren zurückzuführen sind (GC-Kick-In usw.). Denken Sie daran, in diesem Fall kann es keinen Unterschied geben! Mikro-Benchmarks wie diese sind schwer zu finden. Siehe mein Juwelfruity
für ein anständiges Werkzeug dafür.Beachten Sie, dass bei einer Interpolation des Formulars
"...#{...}..."
dies auf atSTRING_DBEG
, eine Reihe vontSTRING_DVAR
für jeden Ausdruck in#{...}
und ein Finale analysiert wirdtSTRING_DEND
. Dies ist jedoch nur dann der Fall, wenn es eine Interpolation gibt, worum es im OP nicht geht.Früher habe ich vorgeschlagen, dass Sie überall doppelte Anführungszeichen verwenden (erleichtert das
#{some_var}
spätere Hinzufügen ), aber jetzt verwende ich einfache Anführungszeichen, es sei denn, ich benötige Interpolation\n
usw. Ich mag es visuell und es ist etwas expliziter, da es keine gibt Sie müssen die Zeichenfolge analysieren, um festzustellen, ob sie einen Ausdruck enthält.quelle
#{n}
, dass die Nummernkonvertierung durchgeführt wird). Zeigt es nicht die Unterschiede beim Parsen?Niemand hat zufällig die Verkettung gegenüber der Interpolation gemessen:
Insbesondere beachten
assign interp = 2.62
vsconcat single = 3.76
. Als Sahnehäubchen finde ich Interpolation auch besser lesbar als'a' + var + 'b'
besonders in Bezug auf Räume.quelle
Kein Unterschied - es sei denn, Sie verwenden die
#{some_var}
Interpolation von Stilzeichenfolgen. Aber Sie erhalten den Leistungseinbruch nur, wenn Sie das tatsächlich tun.Geändert von Zetetics Beispiel:
Ausgabe
quelle
Einfache Anführungszeichen können etwas schneller sein als doppelte Anführungszeichen, da der Lexer nicht nach
#{}
Interpolationsmarkierungen suchen muss. Abhängig von der Implementierung usw. Beachten Sie, dass dies Analysekosten und keine Laufzeitkosten sind.Die eigentliche Frage war jedoch, ob die Verwendung von Zeichenfolgen in doppelten Anführungszeichen "die Leistung auf sinnvolle Weise verringert", auf die die Antwort ein entscheidendes "Nein" lautet. Der Leistungsunterschied ist so unglaublich gering, dass er im Vergleich zu echten Leistungsproblemen völlig unbedeutend ist. Verschwenden Sie nicht Ihre Zeit.
Die tatsächliche Interpolation ist natürlich eine andere Geschichte.
'foo'
wird fast genau 1 Sekunde schneller sein als"#{sleep 1; nil}foo"
.quelle
Doppelte Anführungszeichen erfordern doppelt so viele Tastenanschläge wie einfache Anführungszeichen. Ich habe es immer eilig. Ich benutze einfache Anführungszeichen. :) Und ja, ich halte das für einen "Leistungsgewinn". :) :)
quelle
Ich dachte, ich würde einen Vergleich von 1.8.7 und 1.9.2 hinzufügen. Ich habe sie ein paar Mal ausgeführt. Die Varianz betrug ungefähr + -0,01.
Ruby 1.8.7 (2010-08-16 Patchlevel 302) [x86_64-Linux]
ruby 1.9.2p0 (18.08.2010, Revision 29036) [x86_64-linux]
quelle
Es gibt keinen signifikanten Unterschied in beide Richtungen. Es müsste riesig sein, damit es eine Rolle spielt.
Optimieren Sie die Wartbarkeit des Programmierers, außer in Zeiten, in denen Sie sicher sind, dass tatsächlich ein Problem mit dem Timing vorliegt.
Die Kosten für die Maschinenzeit sind sehr, sehr gering. Die Kosten für die Programmiererzeit zum Schreiben und Verwalten von Code sind enorm.
Was nützt eine Optimierung, um über Tausende von Läufen Sekunden oder sogar Minuten Laufzeit zu sparen, wenn dies bedeutet, dass der Code schwieriger zu warten ist?
Wählen Sie mit einem Stil und bleiben Sie dabei aber nicht wählen diesen Stil basierend auf statistisch insignifikant Millisekunden von der Laufzeit.
quelle
Ich dachte auch, dass einfach zitierte Zeichenfolgen für Ruby schneller zu analysieren sind. Es scheint nicht der Fall zu sein.
Wie auch immer, ich denke, der obige Benchmark misst das Falsche. Es liegt auf der Hand, dass beide Versionen in die gleichen internen Zeichenfolgendarstellungen analysiert werden. Um die Antwort zu erhalten, welche schneller zu analysieren ist, sollten wir die Leistung nicht mit Zeichenfolgenvariablen messen, sondern mit Rubys Geschwindigkeit beim Analysieren von Zeichenfolgen.
Wiederholte Läufe scheinen keinen großen Unterschied zu machen. Es dauert immer noch ziemlich genau die gleiche Zeit, um eine der Versionen des Strings zu analysieren.
quelle
Es ist sicherlich abhängig von der Implementierung möglich, aber der Scan-Teil des Interpreters sollte jedes Zeichen nur einmal betrachten. Es werden nur ein zusätzlicher Status (oder ein möglicher Satz von Status) und Übergänge benötigt, um # {} Blöcke zu verarbeiten.
In einem tabellenbasierten Scanner ist dies eine einzelne Suche, um den Übergang zu bestimmen, und wird sowieso für jedes Zeichen durchgeführt.
Wenn der Parser die Scannerausgabe erhält, ist bereits bekannt, dass er den Code im Block auswerten muss. Der Overhead ist also nur der Speicher-Overhead im Scanner / Parser, um den # {} -Block zu verarbeiten, den Sie in beiden Fällen bezahlen.
Es sei denn, ich vermisse etwas (oder erinnere mich falsch an die Konstruktionsdetails des Compilers), was sicherlich auch möglich ist :)
quelle
quelle
Es gibt einen, den ihr alle vermisst habt.
HIER doc
Versuche dies
Es gab mir
und
Es ist also sicherlich besser als Concat und all diese Puts zu schreiben.
Ich würde gerne sehen, dass Ruby mehr im Sinne einer Dokumentmanipulationssprache unterrichtet wird.
Tun wir das nicht wirklich in Rails, Sinatra und bei laufenden Tests?
quelle
Ich habe Tim Snowhites Antwort modifiziert.
Ergebnisse:
quelle
Ich habe folgendes versucht:
Und das sind die Ergebnisse:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Wenn ich keinen Fehler gemacht habe, scheint es mir, dass beide ungefähr die gleiche Zeit in Anspruch nehmen, obwohl das einfache Anführungszeichen in den meisten Fällen etwas schneller ist.
quelle