[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