[ruby-it] Quattro interpreti ruby a confronto

Marco Mastrodonato m.mastrodonato a gmail.com
Sab 15 Ago 2009 16:58:53 CEST


Paolo Montrasio wrote:
> 
> 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

Paolo, secondo me il confronto tra le concatenazioni e il [].join non è 
equo perchè in questo utilizzi anche degli <<. L'ho modificato 
leggermente, testa anche la generazione delle stringhe (una curiosità in 
piu) ed ho aggiunto anche << anche se utilizzato in questo modo ha poco 
senso ed è poco leggibile.
L'ho fatto girare sul mio portatile Intel core2 Duo T7200 2Ghz (166x12) 
Ram 2Gb 667Mhz WinXP SP3:

require "benchmark"
include Benchmark

Benchmark.bm(21, "--- Total:") do|b|
  puts "1.000.000 iterations:"
  puts "'1000'.create:"
  n=1_000_000
  t1 = b.report("'%01000d' % 0") do
    n.times { "%01000d" % 0 }
  end
  t1 += b.report("0 * 1000") do
    n.times { "0" * 1000 }
  end

  puts "'4000'.create:"
  n=1_000_000
  t1 += b.report("'%04000d' % 0") do
    n.times { "%04000d" % 0 }
  end
  t1 += b.report("0 * 4000") do
    n.times { "0" * 4000 }
  end

  a=[]
  (1..5).each {|x| a << "%01000d" % x}

  puts "1000: str vs [].join:"
  n=1_000_000
  t2 = b.report("+") do
    n.times { a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " " + a[4]; 
a[1] + " " + a[2] }
  end
  t2 += b.report("\#\{\}") do
    n.times { "#{a[0]} #{a[1]} #{a[2]} #{a[3]} #{a[4]}"; "#{a[1]} 
#{a[2]}" }
  end
  t2 = b.report("<<") do
    n.times {
      x = y = ""
      x<<a[0];x<<" ";x<<a[1];x<<" ";x<<a[2];x<<" ";x<<a[3];x<<" 
";x<<a[4]
      y<<a[1];y<<" ";y<<a[2]
    }
  end
  t2 += b.report("[].join") do
    n.times { a.join(" ") }
  end

  [t1+t2]
end

C:\Lavoro\Progetti\Test\Bench>ruby -v
ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]

C:\Lavoro\Progetti\Test\Bench>ruby Join.rb
                           user     system      total        real
1.000.000 iterations:
'1000'.create:
'%01000d' % 0          6.187000   1.281000   7.468000 (  7.593750)
0 * 1000              12.516000   0.390000  12.906000 ( 13.031250)
'4000'.create:
'%04000d' % 0         15.641000   1.875000  17.516000 ( 17.656250)
0 * 4000              45.906000   2.125000  48.031000 ( 48.328125)
1000: str vs [].join:
+                     36.234000  18.985000  55.219000 ( 55.921875)
#{}                   15.125000   4.437000  19.562000 ( 19.812500)
<<                    14.281000   3.703000  17.984000 ( 18.296875)
[].join                5.641000   3.875000   9.516000 (  9.687500)
--- Total:           100.172000  13.249000 113.421000 (114.593750)


In questo caso il .join è molto più veloce degli altri.
Questa è l'esecuzione di ruby 1.9.1:


C:\Lavoro\Progetti\Test\Bench>ruby -v
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-mingw32]

C:\Lavoro\Progetti\Test\Bench>ruby Join.rb
                           user     system      total        real
1.000.000 iterations:
'1000'.create:
'%01000d' % 0         10.984000   1.266000  12.250000 ( 12.312500)
0 * 1000               1.953000   0.547000   2.500000 (  2.515625)
'4000'.create:
'%04000d' % 0         20.125000   2.281000  22.406000 ( 22.578125)
0 * 4000               4.344000   2.938000   7.282000 (  7.343750)
1000: str vs [].join:
+                     36.359000  16.718000  53.077000 ( 53.500000)
#{}                   13.141000   5.516000  18.657000 ( 18.859375)
<<                    15.047000   5.375000  20.422000 ( 20.578125)
[].join                5.891000   4.047000   9.938000 ( 10.031250)
--- Total:            58.344000  16.454000  74.798000 ( 75.359375)



I risultati di elaborazione sono molto simili, il risultato è stravolto 
dai tempi di generazione delle stringhe, su ruby 1.8.6 sono molto alti 
se generate con *, in compenso con % va meglio.
L'utilizzo di memoria (quasi identico tra le due versioni) vede in 
leggero svantaggio .join (picco max di 12Mb) contro 8,5Mb degli altri 
metodi... valutare se è una differenza trascurabile dipende dalla 
complessità del progetto, l'importante è essere a conoscenza delle 
differenze.

Li ho eseguiti anche con jruby e ironruby con risultati molto diversi, 
ironruby è una scheggia quando usa %, conferma le sue migliori 
prestazioni con i numeri rispetto alle stringhe. I dettagli li metterò 
nel mio prossimo articolo ;) (che terminerò quando avrò poco sonno)
-- 
Posted via http://www.ruby-forum.com/.


More information about the Ml mailing list