[ruby-it] Quattro interpreti ruby a confronto
Paolo Montrasio
paolo a paolomontrasio.com
Dom 9 Ago 2009 23:43:45 CEST
Pietro Giorgianni wrote:
> a proposito, se chi ha fatto i benchmark volesse aggiungere alla
> valutazione [].join mi farebbe cosa molto gradita: spesso quando devo
> concatenare tante parti creo un array e faccio join alla fine. faccio
> bene o faccio male?
La risposta breve è: dipende da quanto sono grosse le stringhe, se sono
piccole [].join perde, se sono grandi (diciamo dal kB abbondante in su)
vince.
Segue la risposta lunga.
Leggendo il benchmark mi ha incuriosito proprio la variazione di
performance dei metodi di concatenazione di stringhe, che è
un'operazione che si fa di continuo. Mi sono chiesto allora quale fosse
il metodo più veloce tra tutti.
Ho allora ripetuto il benchmark delle stringhe aggiungendo altri due
metodi di concatenzione, ossia
%(#{stringa1} #{stringa2})
e
a = []; a << stringa1; a << stringa2; a.join(" ")
ed inoltre ho fatto la prova anche con stringhe lunghe, da 500, 1000,
2000 e 4000 caratteri l'una.
Innanzitutto ho notato che ripetendo un po' di volte il test << #{} e
%() risultano praticamente identici. Qualche volta vince uno e qualche
volta vince un altro.
Per stringhe di un carattere la join dell'array è un po' più lenta
mentre per stringhe di 500 caratteri inizia ad avvicinarsi agli altri.
Per stringhe lunghe + diventa estremamente più lento di tutti gli altri
metodi.
Questo è il risultato di un'instanza del test, sperando che la
formattazione sopravviva al post.
user system total real
Concat 1.000.000:
+ 2.370000 0.130000 2.500000 ( 2.532409)
<< 2.310000 0.150000 2.460000 ( 2.493730)
#{} 2.410000 0.180000 2.590000 ( 2.582961)
%() 2.420000 0.150000 2.570000 ( 2.588971)
Array 4.250000 0.170000 4.420000 ( 4.445646)
big + 14.360000 0.240000 14.600000 ( 14.635854)
big #{} 6.210000 0.170000 6.380000 ( 6.401311)
big %() 6.330000 0.180000 6.510000 ( 6.522818)
big Array 6.500000 0.440000 6.940000 ( 6.956503)
Portando le stringhe da concatenare da 500 a 1000 caratteri la
concatenazione con Array rimane al livello degli altri. A 2000 inizia ad
essere leggermente più veloce e a 4000 è decisamente più rapida. Questo
è il caso da 4000:
big + 86.840000 0.270000 87.110000 ( 87.336664)
big #{} 30.950000 0.190000 31.140000 ( 31.217629)
big %() 31.100000 0.270000 31.370000 ( 31.472801)
big Array 26.140000 6.470000 32.610000 ( 32.672105)
I test sono stati eseguiti su un Intel Core Duo 2 T7200 (dual core 2.0
GHz), ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux] 3.4 GB RAM.
Il codice Ruby da aggiungere al benchmark è
t1 = b.report("big +") do
sa="%04000d" % 1; sb="%04000d" % 2; sc="%04000d" % 3;
sd="%04000d" % 4; se="%04000d" % 5
n.times { sa + " " + sb + " " + sc + " " + sd + " " + se; sb + " " +
sc }
end
t1 += b.report("big \#\{\}") do
sa="%04000d" % 1; sb="%04000d" % 2; sc="%04000d" % 3;
sd="%04000d" % 4; se="%04000d" % 5
n.times { "#{sa} #{sb} #{sc} #{sd} #{se}"; "#{sb} #{sc}" }
end
t1 += b.report("big \%\(\)") do
sa="%04000d" % 1; sb="%04000d" % 2; sc="%04000d" % 3;
sd="%04000d" % 4; se="%04000d" % 5
n.times { %(#{sa} #{sb} #{sc} #{sd} #{se}); %(#{sb} #{sc}) }
end
t1 += b.report("big Array") do
sa="%04000d" % 1; sb="%04000d" % 2; sc="%04000d" % 3;
sd="%04000d" % 4; se="%04000d" % 5
n.times { a = []; a << sa; a << sb; a << sc; a << sd; a << se;
a.join(" ");
a = []; a << sb; a << sc; a.join(" ") }
end
Il test big << manca perché come si è già visto nei post precedenti
l'operatore << modifica il suo argomento di sinistra e non avevo voglia
di includere dei literal da 4000 caratteri nel programma.
Conclusione: nella maggior parte dei casi [].join è più lento (e pure
meno leggibile) ma quando i dati sono tanti vale la pena usarlo.
Non ho fatto test per vedere se i vari metodi hanno diverse occupazioni
di memoria. Ci sono volontari?
Paolo
--
Posted via http://www.ruby-forum.com/.
More information about the Ml
mailing list