Intuitivamente, quest'ultimo dovrebbe essere più veloce del precedente. Tuttavia, sono rimasto molto sorpreso quando ho visto i risultati dei benchmark:Cosa è più veloce in Ruby, `arr + = [x]` o `arr << x`
require 'benchmark/ips'
b = (0..20).to_a;
y = 21;
Benchmark.ips do |x|
x.report('<<') { a = b.dup; a << y }
x.report('+=') { a = b.dup; a += [y] }
x.report('push') { a = b.dup; a.push(y) }
x.report('[]=') { a = b.dup; a[a.size]=y }
x.compare!
end
Il risultato è:
Calculating -------------------------------------
<< 24.978k i/100ms
+= 30.389k i/100ms
push 24.858k i/100ms
[]= 22.306k i/100ms
-------------------------------------------------
<< 493.125k (± 3.2%) i/s - 2.473M
+= 599.830k (± 2.3%) i/s - 3.009M
push 476.374k (± 3.3%) i/s - 2.386M
[]= 470.263k (± 3.8%) i/s - 2.364M
Comparison:
+=: 599830.3 i/s
<<: 493125.2 i/s - 1.22x slower
push: 476374.0 i/s - 1.26x slower
[]=: 470262.8 i/s - 1.28x slower
Tuttavia, quando un mio collega ha creato in modo indipendente il proprio punto di riferimento, il risultato è stato tutto il contrario:
Benchmark.ips do |x|
x.report('push') {@a = (0..20).to_a; @a.push(21)}
x.report('<<') {@b = (0..20).to_a; @b << 21}
x.report('+=') {@c = (0..20).to_a; @c += [21]}
x.compare!
end
Risultato:
Calculating -------------------------------------
push 17.623k i/100ms
<< 18.926k i/100ms
+= 16.079k i/100ms
-------------------------------------------------
push 281.476k (± 4.2%) i/s - 1.410M
<< 288.341k (± 3.6%) i/s - 1.457M
+= 219.774k (± 8.3%) i/s - 1.093M
Comparison:
<<: 288341.4 i/s
push: 281476.3 i/s - 1.02x slower
+=: 219774.1 i/s - 1.31x slower
Abbiamo anche incrociato i nostri benchmark e su entrambe le nostre macchine il suo benchmark ha mostrato che +=
è notevolmente più lento di <<
, e il mio ha mostrato il contrario.
Perché è quello?
UPD: la mia versione Ruby è Ruby 2.2.3p173 (2015-08-18 revisione 51636) [x86_64-darwin14]; il mio collega è 2.2.2 (non so tutti i dettagli, aggiornerà il post domani).
UPD2: ruby 2.2.2p95 (2015-04-13 revisione 50295) [x86_64-darwin12.0] versione Ruby del mio compagno di squadra.
È per caso che il benchmark si verifica tra 'dup' e' to_a' perché vedo che c'è una differenza tra due codici? –
In che modo questa differenza spiega perché << è più veloce in un caso ma non nell'altro? – DNNX
Aggiungi la versione di rubino al tuo Q. –