Czy użycie cudzysłowów pojedynczych w porównaniu z podwójnymi cudzysłowami w języku ruby ​​daje wzrost wydajności?


126

Czy wiesz, czy używanie podwójnych cudzysłowów zamiast pojedynczych cudzysłowów w Rubim zmniejsza wydajność w znaczący sposób w Rubim 1.8 i 1.9?

więc jeśli napiszę

question = 'my question'

czy to jest szybsze niż

question = "my question"

Wyobrażam sobie, że ruby ​​próbuje dowiedzieć się, czy coś wymaga oceny, kiedy napotyka podwójne cudzysłowy i prawdopodobnie spędza kilka cykli, robiąc to.


17
Uruchom go pół miliona razy i zobacz. Są szanse, że Twoja witryna nie ma wystarczającego ruchu, aby mieć znaczenie. Przedwczesna optymalizacja generalnie nie jest tego warta.
ceejayoz

60
dlaczego tak wiele osób oczekuje, że ruby ​​będzie używany tylko do programowania w sieci?
johannes

17
Nie rozważałbym tej przedwczesnej optymalizacji. To bardziej „sprawdzona metoda”, ponieważ powrót po ukończeniu aplikacji i optymalizacja pod kątem pojedynczej lub podwójnej aplikacji byłaby ogromnym bólem głowy.
Omar

7
Dla mnie to tylko styl: używam pojedynczych cudzysłowów dla „statycznych” łańcuchów i podwójnych qoutów (lub innych interpolowanych ciągów znaków) w innych przypadkach.
tig

3
@Baddie: Jest to przedwczesna optymalizacja, jeśli optymalizujesz problem, który nie istnieje.
Andy Lester

Odpowiedzi:


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)

Uwaga: zaktualizowałem to, aby działało z nowszymi wersjami Rubiego, wyczyściłem nagłówek i uruchomiłem test porównawczy na szybszym systemie.

Ta odpowiedź pomija kilka kluczowych punktów. Zobacz zwłaszcza te inne odpowiedzi dotyczące interpolacji i powodu, dla którego nie ma znaczącej różnicy w wydajności przy użyciu apostrofów i cudzysłowów.


Czy poprawnie interpretuję wyniki? Zadanie przy użyciu podwójnych cudzysłowów jest rzeczywiście szybsze niż pojedyncze? Jak to może być?
randomguy

Najwyraźniej tak, choć różnica jest niewielka. A co do tego - bije mnie.
zetetic

Ten wzorzec byłby o wiele bardziej przekonujący, gdyby uwzględniał czas kompilacji, a także czas wykonania.
nohat

9
Zmierzone różnice nie mają znaczenia. Samo zamówienie (z powodu zbierania śmieci) może mieć istotne znaczenie. Nie ma różnicy w czasie wykonywania między 'i, "ponieważ są one analizowane do tego samego.
Marc-André Lafortune

104

Podsumowanie: brak różnicy prędkości; ten wspaniały, oparty na współpracy przewodnik po stylu Ruby zaleca zachowanie spójności. Teraz używam 'string'chyba, że ​​potrzebna jest interpolacja (opcja A w przewodniku) i podoba mi się, ale zwykle zobaczysz więcej kodu z "string".

Detale:

Teoretycznie może to mieć znaczenie, gdy twój kod jest parsowany , ale nie tylko jeśli nie obchodzi cię ogólnie czas parsowania (pomijalny w porównaniu z czasem wykonania), nie będziesz w stanie znaleźć znaczącej różnicy w tym przypadku.

Ważne jest to, że kiedy zostanie wykonany , będzie dokładnie taki sam .

Benchmarking pokazuje tylko brak zrozumienia, jak działa Ruby. W obu przypadkach ciągi zostaną przeanalizowane do a tSTRING_CONTENT(zobacz źródło wparse.y ). Innymi słowy, procesor wykonuje dokładnie te same operacje podczas tworzenia 'string'lub "string". Te same bity będą odwracane dokładnie w ten sam sposób. Benchmarking pokaże tylko różnice, które nie są znaczące i spowodowane innymi czynnikami (włącza się GC itp.); pamiętaj, w tym przypadku nie może być żadnej różnicy! Takie mikro testy porównawcze są trudne do wykonania. Zobacz mój klejnot fruityza przyzwoite narzędzie do tego.

Zwróć uwagę, że jeśli występuje interpolacja formularza "...#{...}...", zostanie ona przetworzona do a tSTRING_DBEG, kilku tSTRING_DVARdla każdego wyrażenia in #{...}i finału tSTRING_DEND. Dzieje się tak tylko wtedy, gdy występuje interpolacja, a nie o to chodzi w PO.

Kiedyś sugerowałem, abyś wszędzie używał podwójnych cudzysłowów (ułatwia to #{some_var}późniejsze dodanie ), ale teraz używam pojedynczych cudzysłowów, chyba że potrzebuję interpolacji \n, itp ... Podoba mi się wizualnie i jest nieco bardziej wyraźny, ponieważ nie ma trzeba przeanalizować ciąg, aby sprawdzić, czy zawiera jakieś wyrażenie.


3
Wydaje się znacznie ważniejsze niż niewielka różnica w wydajności. To podwójne cudzysłowy!
Venkat D.

Dziękuję za wskazanie mi twojej odpowiedzi. Czy mógłbyś wyjaśnić, dlaczego twierdzisz, że analiza porównawcza jest myląca? Zgadzam się, że różnice są prawdopodobnie nieistotne, ale czy punkt odniesienia jest w jakiś sposób błędny? (Ktoś już podkreślił, #{n}że będzie wykonywał konwersję liczb). Czy to nie pokazuje różnic w analizowaniu?
PhilT

1
Dziękuję za link do przewodnika po stylach. Nie mogę uwierzyć, że wcześniej tego nie spotkałem.
PhilT

1
Poradnik stylów wspomniany w Twojej odpowiedzi został zaktualizowany, aby sugerować przyjęcie spójnego stylu, niezależnie od tego, czy są to pojedyncze czy podwójne cudzysłowy, i wskazuje, że podwójne cudzysłowy są bardziej rozpowszechnione w społeczności Rubiego.
philtr

Użyj cudzysłowów. Programowanie jest trudne. Składnia jest z natury złożona. Podwójne cudzysłowy oznaczają, że nigdy nie popełnisz błędu ani nie będziesz tracić czasu na błąd podczas tworzenia dynamicznego ciągu. W przypadku podwójnych cudzysłowów masz o jedną rzecz mniej do przemyślenia.
Kelsey Hannan

35

Nikt jednak nie zmierzył konkatenacji w porównaniu z interpolacją:

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

W szczególności należy pamiętać assign interp = 2.62vs concat single = 3.76. Wisienką na torcie jest też interpolacja, która jest bardziej czytelna niż 'a' + var + 'b'zwłaszcza w odniesieniu do przestrzeni.


+1. To jedyny wzorzec interpolacji porównujący jabłka z jabłkami.
Mark Thomas

1
Benchmarking może wprowadzać w błąd; zobacz moją odpowiedź, dlaczego. Jeśli chodzi o porównanie konkatenacji i interpolacji, powinno być oczywiste, że interpolacja nie może być wolniejsza niż konkatenacja. W każdym razie to nie jest część pytania!
Marc-André Lafortune

Czy możesz dodać << do tego testu?
Nick

16

Bez różnicy - chyba że używasz #{some_var}interpolacji ciągów stylów. Ale wydajność osiągniesz tylko wtedy, gdy faktycznie to zrobisz.

Zmodyfikowano na podstawie przykładu Zetetic :

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

wynik

               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)

Ciekawy. Interpolacja wygląda nieco drożej. Czy to było 1.8? Fajnie by było zobaczyć, czy 1.9 coś zmieni.
zetetic

zetetic - tak. To było przeciwko Ruby 1.8.7
madlep

1
Wersja interpoluje zarówno interpolację, jak i konkatenację oraz dwukrotną konwersję liczby na ciąg. Interpolacja wygrywa, jeśli wyniki będą takie same. Zobacz gist.github.com/810463 . Prawdziwym rozwiązaniem jest martwienie się bardziej o to_s niż pojedyncze lub podwójne cudzysłowy.
Brian Deterling

Tylko testy porównawcze mogą wprowadzać w błąd i pokazują niezrozumienie tego, jak działa Ruby. Zobacz moją odpowiedź.
Marc-André Lafortune

13

Pojedyncze cudzysłowy mogą być nieco szybsze niż podwójne cudzysłowy, ponieważ lekser nie musi sprawdzać #{}znaczników interpolacji. W zależności od implementacji itp. Należy pamiętać, że jest to koszt czasu analizy, a nie koszt czasu wykonania.

To powiedziawszy, rzeczywiste pytanie brzmiało, czy użycie podwójnych cudzysłowów „zmniejsza wydajność w jakikolwiek znaczący sposób”, na co odpowiedź brzmi „nie”. Różnica w wydajności jest tak niewiarygodnie mała, że ​​jest zupełnie nieistotna w porównaniu z rzeczywistymi problemami z wydajnością. Nie trać czasu.

Rzeczywista interpolacja to oczywiście inna historia. 'foo'będzie prawie dokładnie 1 sekundę szybszy niż "#{sleep 1; nil}foo".


4
+1 za zauważenie, że koszt jest w czasie kompilacji, a nie w czasie wykonywania, więc powyższe odpowiedzi oparte na testach porównawczych, które zostały wysoko ocenione, są mylące.
nohat

„Jest to koszt w czasie analizy, a nie koszt w czasie wykonywania”. to kluczowa fraza.
Tin Man

9

Podwójne cudzysłowy wymagają dwa razy więcej naciśnięć klawiszy niż pojedyncze cudzysłowy. Zawsze mi się spieszy. Używam pojedynczych cudzysłowów. :) I tak, uważam to za „wzrost wydajności”. :)


Dlaczego podwójne cudzysłowy miałyby dwukrotnie przekraczać uderzenia klawiszy? Oba są reprezentowane przez jeden klucz. Ponadto wiele środowisk IDE automatycznie dodaje cudzysłowy zamykające.
Matt Dressel

3
Nawet jeśli IDE automatycznie zamyka cytat, podwójne cudzysłowy nadal wymagają 100% więcej naciśnięć klawiszy. ;-)
Clint Pachl

Matt Dressel: podwójne cudzysłowy wymagają dwukrotnej liczby naciśnięć klawiszy, ponieważ trzeba także nacisnąć klawisz Shift. Och: :) na wypadek, gdybyś przegapił to w moim oryginalnym komentarzu. :) Klucze przewodowe wymagają więcej wysiłku i prawdopodobnie więcej czasu, aby wykonać. :)
aqn

1
Czasami kieruję się tą radą z lenistwa. Ale niestety w niektórych innych językach jest odwrotnie (np. Pojedyncze cudzysłowy wymagają Shift + coś, podczas gdy podwójne cudzysłowy to pojedyncze naciśnięcie klawisza). Niefortunne, ponieważ jeśli dwie osoby z różnymi układami klawiatury pracują nad tym samym projektem, jedna z nich będzie musiała poświęcić kilka naciśnięć klawiszy :)
Halil Özgür

„Jestem człowiekiem w pośpiechu” - jeśli nie naciśniesz Shift i 2 (lub jakiegokolwiek innego klawisza to jest) jeden po drugim, nie oszczędzasz czasu, używając pojedynczych cudzysłowów.
Machisuji

8

Pomyślałem, że dodam porównanie 1.8.7 i 1.9.2. Prowadziłem je kilka razy. Wariancja wynosiła około + -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 poziom poprawki 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 (2010-08-18 wersja 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)

Interp musi dokonać konwersji liczb na łańcuchy. Zobacz gist.github.com/810463 .
Brian Deterling

Zobacz moją odpowiedź, dlaczego otrzymujesz te liczby.
Marc-André Lafortune

Dobra uwaga na temat Interp. Właśnie skopiowałem poprzednią odpowiedź jako podstawę dla mojej. To mnie nauczy.
PhilT

3

Nie ma znaczącej różnicy w żadnym kierunku. Musiałby być ogromny, żeby miał znaczenie.

Z wyjątkiem sytuacji, w których masz pewność, że występuje rzeczywisty problem z synchronizacją, zoptymalizuj je pod kątem łatwości konserwacji przez programistę.

Koszty czasu pracy maszyn są bardzo małe. Koszty czasu programisty na napisanie kodu i utrzymanie go są ogromne.

Jaki pożytek daje optymalizacja, aby zaoszczędzić sekundy, a nawet minuty czasu działania w tysiącach uruchomień, jeśli oznacza to, że kod jest trudniejszy do utrzymania?

Wybierz styl i trzymaj się go, ale nie wybieraj tego stylu na podstawie statystycznie nieistotnych milisekund czasu działania.


1

Też myślałem, że pojedyncze cudzysłowy mogą być szybsze do przeanalizowania dla Rubiego. Wydaje się, że tak nie jest.

W każdym razie myślę, że powyższy test porównawczy mierzy niewłaściwą rzecz. Jest zrozumiałe, że obie wersje zostaną przeanalizowane do tych samych wewnętrznych reprezentacji ciągów, więc aby uzyskać odpowiedź, która z nich jest szybsza do przeanalizowania, nie powinniśmy mierzyć wydajności za pomocą zmiennych łańcuchowych, ale raczej szybkość przetwarzania łańcuchów przez Rubiego.

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

Wydaje się, że powtarzane biegi nie mają większego znaczenia. Wciąż zajmuje mniej więcej tyle samo czasu, aby przeanalizować każdą wersję ciągu.


0

Z pewnością jest to możliwe w zależności od implementacji, ale część skanująca interpretera powinna patrzeć na każdy znak tylko raz. Będzie potrzebował tylko dodatkowego stanu (lub możliwego zestawu stanów) i przejść do obsługi bloków # {}.

W skanerze opartym na tabeli będzie to jedno wyszukiwanie w celu określenia przejścia i tak czy inaczej będzie się to działo dla każdego znaku.

Kiedy parser otrzyma dane wyjściowe skanera, już wiadomo, że będzie musiał ocenić kod w bloku. Więc narzut jest tak naprawdę tylko narzutem pamięci w skanerze / parserze do obsługi bloku # {}, za który płacisz w obu przypadkach.

Chyba że czegoś mi brakuje (lub źle pamiętam szczegóły konstrukcji kompilatora), co też jest na pewno możliwe :)


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)

0

Jest jeden, którego wszyscy przegapiliście.

TUTAJ doc

Spróbuj tego

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

To dało mi

`asign here doc  0.141000   0.000000   0.141000 (  0.140625)`

i

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

więc jest to z pewnością lepsze niż konkatowanie i pisanie tych wszystkich wstawień.

Chciałbym, aby Ruby uczył czegoś więcej na wzór języka manipulacji dokumentami.

W końcu, czy naprawdę nie robimy tego w Railsach, Sinatrze i testach?


0

Zmodyfikowałem odpowiedź Tima Snowhite'a.

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

Wyniki:

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)

0

Próbowałem następujących rzeczy:

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

A oto wyniki:

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

Jeśli się nie pomyliłem, wydaje mi się, że oba zajmują mniej więcej tyle samo czasu, chociaż pojedyncze cudzysłowy są w większości przypadków nieco szybsze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.