Gibt es einen Leistungsgewinn bei der Verwendung von einfachen Anführungszeichen gegenüber doppelten Anführungszeichen in Ruby?

126

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.

dimus
quelle
17
Führen Sie es eine halbe Million Mal aus und sehen Sie. Es besteht die Möglichkeit, dass Ihre Website nicht annähernd genug Verkehr erhält, um eine Rolle zu spielen. Eine vorzeitige Optimierung lohnt sich in der Regel nicht.
Ceejayoz
60
Warum erwarten so viele Menschen, dass Rubin nur für die Webprogrammierung verwendet wird?
Johannes
17
Ich würde diese vorzeitige Optimierung nicht in Betracht ziehen. Eher eine "Best Practice", da die Rückkehr nach Abschluss Ihrer App und die Optimierung für Einzel- oder Doppelanwendungen massive Kopfschmerzen verursachen würden.
Omar
7
Für mich ist es nur Stil: In anderen Fällen verwende ich einfache Anführungszeichen für 'statische' Zeichenfolgen und doppelte Qoutes (oder andere interpolierte Zeichenfolgen).
Tig
3
@Baddie: Es ist eine vorzeitige Optimierung, wenn Sie ein nicht vorhandenes Problem optimieren.
Andy Lester

Antworten:

86
$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.0.0]

$ cat benchmark_quotes.rb
# As of Ruby 1.9 Benchmark must be required
require 'benchmark'

n = 1000000
Benchmark.bm(15) do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby benchmark_quotes.rb 

                      user     system      total        real
assign single     0.110000   0.000000   0.110000 (  0.116867)
assign double     0.120000   0.000000   0.120000 (  0.116761)
concat single     0.280000   0.000000   0.280000 (  0.276964)
concat double     0.270000   0.000000   0.270000 (  0.278146)

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.

zetetisch
quelle
Interpretiere ich die Ergebnisse richtig? Zuweisung mit doppelten Anführungszeichen ist tatsächlich schneller als einfache? Wie kann das sein?
Randomguy
Anscheinend ja, obwohl der Unterschied gering ist. Warum - schlägt mich.
Zetetic
Dieser Benchmark wäre viel überzeugender, wenn sowohl die Kompilierungszeit als auch die Ausführungszeit berücksichtigt würden.
nohat
9
Die gemessenen Unterschiede sind nicht aussagekräftig. Nur die Reihenfolge (wegen der Speicherbereinigung) kann einen wichtigen Unterschied machen. Es gibt keinen Laufzeitunterschied zwischen 'und, "da sie auf dasselbe analysiert werden.
Marc-André Lafortune
104

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 Juwel fruityfür ein anständiges Werkzeug dafür.

Beachten Sie, dass bei einer Interpolation des Formulars "...#{...}..."dies auf a tSTRING_DBEG, eine Reihe von tSTRING_DVARfür jeden Ausdruck in #{...}und ein Finale analysiert wird tSTRING_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 \nusw. 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.

Marc-André Lafortune
quelle
3
Scheint viel wichtiger als der winzige Leistungsunterschied. Doppelte Anführungszeichen ist es!
Venkat D.
Vielen Dank, dass Sie mich auf Ihre Antwort hingewiesen haben. Können Sie klarstellen, warum Sie sagen, dass das Benchmarking irreführend ist? Ich stimme zu, dass die Unterschiede wahrscheinlich vernachlässigbar sind, aber ist der Benchmark in irgendeiner Weise falsch? (Jemand hat bereits hervorgehoben #{n}, dass die Nummernkonvertierung durchgeführt wird). Zeigt es nicht die Unterschiede beim Parsen?
PhilT
1
Vielen Dank für den Link zum Styleguide. Ich kann nicht glauben, dass ich das vorher nicht gesehen habe.
PhilT
1
Der in Ihrer Antwort erwähnte Styleguide wurde aktualisiert , um die Verwendung eines konsistenten Stils vorzuschlagen, unabhängig davon, ob es sich um einfache oder doppelte Anführungszeichen handelt, und zeigt an, dass Zeichenfolgen mit doppelten Anführungszeichen in der Ruby-Community häufiger vorkommen.
Philtr
Verwenden Sie doppelte Anführungszeichen. Die Programmierung ist schwierig. Die Syntax ist von Natur aus komplex. Doppelte Anführungszeichen bedeuten, niemals einen Fehler zu machen oder Zeit mit einem Fehler zu verschwenden, wenn eine Zeichenfolge dynamisch gemacht wird. Bei doppelten Anführungszeichen müssen Sie an eine Sache weniger denken.
Kelsey Hannan
35

Niemand hat zufällig die Verkettung gegenüber der Interpolation gemessen:

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.6.2]
$ cat benchmark_quotes.rb
require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a string #{'b string'}"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby -w benchmark_quotes.rb 
      user     system      total        real
assign single  2.600000   1.060000   3.660000 (  3.720909)
assign double  2.590000   1.050000   3.640000 (  3.675082)
assign interp  2.620000   1.050000   3.670000 (  3.704218)
concat single  3.760000   1.080000   4.840000 (  4.888394)
concat double  3.700000   1.070000   4.770000 (  4.818794)

Insbesondere beachten assign interp = 2.62vs concat single = 3.76. Als Sahnehäubchen finde ich Interpolation auch besser lesbar als 'a' + var + 'b'besonders in Bezug auf Räume.

Tim Snowhite
quelle
+1. Dies ist der einzige Interpolations-Benchmark, der Äpfel mit Äpfeln vergleicht.
Mark Thomas
1
Benchmarking kann irreführend sein. siehe meine Antwort für warum. Beim Vergleich zwischen Verkettung und Interpolation sollte klar sein, dass die Interpolation nicht langsamer sein kann als die Verkettung. Das ist jedenfalls nicht wirklich Teil der Frage!
Marc-André Lafortune
Können Sie diesem Test << hinzufügen?
Nick
16

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:

require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a #{n} string"; end}  
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
  x.report("concat interp") { n.times do; "a #{n} string " + "b #{n} string"; end}
end

Ausgabe

               user       system     total    real
assign single  0.370000   0.000000   0.370000 (  0.374599)
assign double  0.360000   0.000000   0.360000 (  0.366636)
assign interp  1.540000   0.010000   1.550000 (  1.577638)
concat single  1.100000   0.010000   1.110000 (  1.119720)
concat double  1.090000   0.000000   1.090000 (  1.116240)
concat interp  3.460000   0.020000   3.480000 (  3.535724)
Madlep
quelle
Interessant. Interpolation sieht etwas teurer aus. War das 1,8? Es wäre schön zu sehen, ob 1.9 etwas ändert.
Zetetic
zetetic - yup. Dies war gegen Ruby 1.8.7
Madlep
1
Die Interp-Version interpoliert und verkettet und konvertiert eine Zahl zweimal in eine Zeichenfolge. Die Interpolation gewinnt, wenn Sie die Ergebnisse gleich machen. Siehe gist.github.com/810463 . Der eigentliche Vorteil besteht darin, sich mehr um to_s als um einfache oder doppelte Anführungszeichen zu kümmern.
Brian Deterling
Das Benchmarking kann nur irreführend sein und zeigt ein Missverständnis der Funktionsweise von Ruby. Siehe meine Antwort.
Marc-André Lafortune
13

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".

Rein Henrichs
quelle
4
+1 für die Feststellung, dass die Kosten zur Kompilierungszeit und nicht zur Laufzeit anfallen. Daher sind die oben genannten Antworten auf der Grundlage von Benchmarks irreführend.
nohat
"Dies sind Analysekosten, keine Laufzeitkosten." ist der Schlüsselbegriff.
der Blechmann
9

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". :) :)

aqn
quelle
Warum sollten doppelte Anführungszeichen das Zweifache der Schlüsselschläge erfordern? Sie werden beide durch einen einzigen Schlüssel dargestellt. Darüber hinaus fügen viele IDEs die Abschlusszitate automatisch hinzu.
Matt Dressel
3
Selbst wenn die IDE das Angebot automatisch schließt, erfordern doppelte Anführungszeichen immer noch 100% mehr Schlüsselschläge. ;-)
Clint Pachl
Matt Dressel: Doppelte Anführungszeichen erfordern die doppelte Anzahl von Tastenanschlägen, da Sie auch die Umschalttaste drücken müssen. Oh: :) Nur für den Fall, dass du es in meinem ursprünglichen Kommentar verpasst hast. :) Kabelgebundene Schlüssel erfordern mehr Aufwand und wahrscheinlich mehr Zeit für die Ausführung. :)
aqn
1
Manchmal folge ich diesem Rat aus Faulheit. In einigen anderen Sprachen ist es leider umgekehrt (z. B. benötigen einfache Anführungszeichen Umschalt + etwas, während doppelte Anführungszeichen ein einfacher Tastendruck sind). Schade, denn wenn zwei Personen mit unterschiedlichen Tastaturlayouts am selben Projekt arbeiten, muss einer von ihnen einige Tastenanschläge opfern :)
Halil Özgür
"Ich bin ein Mann in Eile" - Wenn Sie nicht nacheinander Umschalt und 2 (oder eine andere Taste) drücken, sparen Sie überhaupt keine Zeit, indem Sie einfache Anführungszeichen verwenden.
Machisuji
8

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.

require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a #{n} string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
  x.report("concat interp") { n.times do; "a #{n} string " + "b #{n} string"; end}
end

Ruby 1.8.7 (2010-08-16 Patchlevel 302) [x86_64-Linux]

assign single  0.180000   0.000000   0.180000 (  0.187233)
assign double  0.180000   0.000000   0.180000 (  0.187566)
assign interp  0.880000   0.000000   0.880000 (  0.877584)
concat single  0.550000   0.020000   0.570000 (  0.567285)
concat double  0.570000   0.000000   0.570000 (  0.570644)
concat interp  1.800000   0.010000   1.810000 (  1.816955)

ruby 1.9.2p0 (18.08.2010, Revision 29036) [x86_64-linux]

  user          system      total      real
assign single  0.140000   0.000000   0.140000 (  0.144076)
assign double  0.130000   0.000000   0.130000 (  0.142316)
assign interp  0.650000   0.000000   0.650000 (  0.656088)
concat single  0.370000   0.000000   0.370000 (  0.370663)
concat double  0.370000   0.000000   0.370000 (  0.370076)
concat interp  1.420000   0.000000   1.420000 (  1.412210)
PhilT
quelle
Interp muss Konvertierungen von Zahlen in Zeichenfolgen durchführen. Siehe gist.github.com/810463 .
Brian Deterling
Siehe meine Antwort, warum Sie diese Zahlen erhalten.
Marc-André Lafortune
Guter Punkt auf der Interp. Ich hatte gerade die vorherige Antwort als Grundlage für meine kopiert. Das wird mich lehren.
PhilT
3

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.

Andy Lester
quelle
1

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.

generate.rb: 
10000.times do
  ('a'..'z').to_a.each {|v| print "#{v}='This is a test string.'\n" }
end

#Generate sample ruby code with lots of strings to parse
$ ruby generate.rb > single_q.rb
#Get the double quote version
$ tr \' \" < single_q.rb > double_q.rb

#Compare execution times
$ time ruby single_q.rb 

real    0m0.978s
user    0m0.920s
sys     0m0.048s
$ time ruby double_q.rb 

real    0m0.994s
user    0m0.940s
sys     0m0.044s

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.

PSkocik
quelle
0

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 :)

µBio
quelle
0
~ > ruby -v   
jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_37) [darwin-x86_64-java]
~ > cat qu.rb 
require 'benchmark'

n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end
~ > ruby qu.rb
      user     system      total        real
assign single  0.186000   0.000000   0.186000 (  0.151000)
assign double  0.062000   0.000000   0.062000 (  0.062000)
concat single  0.156000   0.000000   0.156000 (  0.156000)
concat double  0.124000   0.000000   0.124000 (  0.124000)
grilix
quelle
0

Es gibt einen, den ihr alle vermisst habt.

HIER doc

Versuche dies

require 'benchmark'
mark = <<EOS
a string
EOS
n = 1000000
Benchmark.bm do |x|
  x.report("assign here doc") {n.times do;  mark; end}
end

Es gab mir

`asign here doc  0.141000   0.000000   0.141000 (  0.140625)`

und

'concat single quotes  1.813000   0.000000   1.813000 (  1.843750)'
'concat double quotes  1.812000   0.000000   1.812000 (  1.828125)'

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?

Douglas G. Allen
quelle
0

Ich habe Tim Snowhites Antwort modifiziert.

require 'benchmark'
n = 1000000
attr_accessor = :a_str_single, :b_str_single, :a_str_double, :b_str_double
@a_str_single = 'a string'
@b_str_single = 'b string'
@a_str_double = "a string"
@b_str_double = "b string"
@did_print = false
def reset!
    @a_str_single = 'a string'
    @b_str_single = 'b string'
    @a_str_double = "a string"
    @b_str_double = "b string"
end
Benchmark.bm do |x|
    x.report('assign single       ') { n.times do; c = 'a string'; end}
    x.report('assign via << single') { c =''; n.times do; c << 'a string'; end}
    x.report('assign double       ') { n.times do; c = "a string"; end}
    x.report('assing interp       ') { n.times do; c = "a string #{'b string'}"; end}
    x.report('concat single       ') { n.times do; 'a string ' + 'b string'; end}
    x.report('concat double       ') { n.times do; "a string " + "b string"; end}
    x.report('concat single interp') { n.times do; "#{@a_str_single}#{@b_str_single}"; end}
    x.report('concat single <<    ') { n.times do; @a_str_single << @b_str_single; end}
    reset!
    # unless @did_print
    #   @did_print = true
    #   puts @a_str_single.length 
    #   puts " a_str_single: #{@a_str_single} , b_str_single: #{@b_str_single} !!"
    # end
    x.report('concat double interp') { n.times do; "#{@a_str_double}#{@b_str_double}"; end}
    x.report('concat double <<    ') { n.times do; @a_str_double << @b_str_double; end}
end

Ergebnisse:

jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_10-b18 [darwin-x86_64]
       user     system      total        real
assign single         0.220000   0.010000   0.230000 (  0.108000)
assign via << single  0.280000   0.010000   0.290000 (  0.138000)
assign double         0.050000   0.000000   0.050000 (  0.047000)
assing interp         0.100000   0.010000   0.110000 (  0.056000)
concat single         0.230000   0.010000   0.240000 (  0.159000)
concat double         0.150000   0.010000   0.160000 (  0.101000)
concat single interp  0.170000   0.000000   0.170000 (  0.121000)
concat single <<      0.100000   0.000000   0.100000 (  0.076000)
concat double interp  0.160000   0.000000   0.160000 (  0.108000)
concat double <<      0.100000   0.000000   0.100000 (  0.074000)

ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.4.0]
       user     system      total        real
assign single         0.100000   0.000000   0.100000 (  0.103326)
assign via << single  0.160000   0.000000   0.160000 (  0.163442)
assign double         0.100000   0.000000   0.100000 (  0.102212)
assing interp         0.110000   0.000000   0.110000 (  0.104671)
concat single         0.240000   0.000000   0.240000 (  0.242592)
concat double         0.250000   0.000000   0.250000 (  0.244666)
concat single interp  0.180000   0.000000   0.180000 (  0.182263)
concat single <<      0.120000   0.000000   0.120000 (  0.126582)
concat double interp  0.180000   0.000000   0.180000 (  0.181035)
concat double <<      0.130000   0.010000   0.140000 (  0.128731)
Nick
quelle
0

Ich habe folgendes versucht:

def measure(t)
  single_measures = []
  double_measures = []
  double_quoted_string = ""
  single_quoted_string = ''
  single_quoted = 0
  double_quoted = 0

  t.times do |i|
    t1 = Time.now
    single_quoted_string << 'a'
    t1 = Time.now - t1
    single_measures << t1

    t2 = Time.now
    double_quoted_string << "a"
    t2 = Time.now - t2
    double_measures << t2

    if t1 > t2 
      single_quoted += 1
    else
      double_quoted += 1
    end
  end
  puts "Single quoted did took longer in #{((single_quoted.to_f/t.to_f) * 100).round(2)} percent of the cases"
  puts "Double quoted did took longer in #{((double_quoted.to_f/t.to_f) * 100).round(2)} percent of the cases"

  single_measures_avg = single_measures.inject{ |sum, el| sum + el }.to_f / t
  double_measures_avg = double_measures.inject{ |sum, el| sum + el }.to_f / t
  puts "Single did took an average of #{single_measures_avg} seconds"
  puts "Double did took an average of #{double_measures_avg} seconds"
    puts "\n"
end
both = 10.times do |i|
  measure(1000000)
end

Und das sind die Ergebnisse:

1.

Single quoted did took longer in 32.33 percent of the cases
Double quoted did took longer in 67.67 percent of the cases
Single did took an average of 5.032084099982639e-07 seconds
Double did took an average of 5.171539549983464e-07 seconds

2.

Single quoted did took longer in 26.9 percent of the cases
Double quoted did took longer in 73.1 percent of the cases
Single did took an average of 4.998066229983696e-07 seconds
Double did took an average of 5.223457359986066e-07 seconds

3.

Single quoted did took longer in 26.44 percent of the cases
Double quoted did took longer in 73.56 percent of the cases
Single did took an average of 4.97640888998877e-07 seconds
Double did took an average of 5.132918459987151e-07 seconds

4.

Single quoted did took longer in 26.57 percent of the cases
Double quoted did took longer in 73.43 percent of the cases
Single did took an average of 5.017136069985988e-07 seconds
Double did took an average of 5.004514459988143e-07 seconds

5.

Single quoted did took longer in 26.03 percent of the cases
Double quoted did took longer in 73.97 percent of the cases
Single did took an average of 5.059069689983285e-07 seconds
Double did took an average of 5.028807639983705e-07 seconds

6.

Single quoted did took longer in 25.78 percent of the cases
Double quoted did took longer in 74.22 percent of the cases
Single did took an average of 5.107472039991399e-07 seconds
Double did took an average of 5.216212339990241e-07 seconds

7.

Single quoted did took longer in 26.48 percent of the cases
Double quoted did took longer in 73.52 percent of the cases
Single did took an average of 5.082368429989468e-07 seconds
Double did took an average of 5.076817109989933e-07 seconds

8.

Single quoted did took longer in 25.97 percent of the cases
Double quoted did took longer in 74.03 percent of the cases
Single did took an average of 5.077162969990005e-07 seconds
Double did took an average of 5.108381859991112e-07 seconds

9.

Single quoted did took longer in 26.28 percent of the cases
Double quoted did took longer in 73.72 percent of the cases
Single did took an average of 5.148080479983138e-07 seconds
Double did took an average of 5.165793929982176e-07 seconds

10.

Single quoted did took longer in 25.03 percent of the cases
Double quoted did took longer in 74.97 percent of the cases
Single did took an average of 5.227828659989748e-07 seconds
Double did took an average of 5.218296609988378e-07 seconds

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.

Marcelo Xavier
quelle