From: Benoit Daloze Date: 2009-11-29T06:21:51+09:00 Subject: Re: Ruby internals & other questions --0016e65aef4001adb9047974ffdb Content-Type: text/plain; charset=ISO-8859-1 Ah? realtime { p (1..1_000_000).inject {|s,e| s + e} } => 0.15593600273132324 realtime { p (1..1_000_000).inject(&:+) } => 0.1163489818572998 realtime { p (1..1_000_000).inject(:+) } => 0.08730292320251465 realtime { y=0; (1..1_000_000).each {|x| y+=x}; p y } => 0.12649822235107422 realtime { y=0; 1.upto(1_000_000) {|x| y+=x}; p y } => 0.12580513954162598 realtime { y=0;i=0; while(i<1_000_000); i+=1;y+=i; end; p y } => 0.05157589912414551 realtime { y=0; for i in (1..1_000_000); y+=i; end; p y } => 0.13959503173828125 Seem the inject(:+), which is a bit less idiomatic, is clearly better to do this. And clearly inject is fast and good for memory I think (no outside local variables needed, that's its power). The while loop is the fastest, while completely looking awful. (1) Does the block get compiled a million times? No (2) What's the best Ruby way to do a sum from 1 to 1_000_000 => The most "Ruby way" is inject to sum values in an Array (3) Is there a difference in speed between IRB.exe and ruby.exe in executing the above code? Let's see: IRB > realtime { p (1..1_000_000).inject(:+) } => 0.08730292320251465 RUBY > ruby test.rb 0.08849906921386719 It's the same. IRB even look better here. (4) In IRB, whats the best way to time the code, above? require "benchmark" include Benchmark p realtime { p (1..1_000_000).inject(:+) } If you more details, look Benchmark module. require "benchmark" include Benchmark bm { |b| b.report("mytest") { (1..1_000_000).inject(:+) } } 2009/11/25 Kirk Haines > On Wed, Nov 25, 2009 at 9:29 AM, Aldric Giacomoni >wrote: > > > Ralph Shnelvar wrote: > > > > > > y=0 > > > 1_000_000.times {|x| y+=x} > > > > y = (1..1_000_000).inject { |a, b| a + b } > > > > More idiomatic, though maybe yours is easier to read at first. > > > > Ugh. His, while wrong for what he is trying to do (sum from 1 to 1000000) > is vastly superior to using inject like that. It's not idiomatic. It's > obtuse. > > If one really wants to figure it out iteratively: > > y = 0; 1.upto(1000000) {|x| y += x} > > or > > y = 0; (1..1000000).each {|x| y += x} > > Are both easier to read at first, at second, and at 1000000 viewings than > using inject is. Additionally, inject has no advantage with regard to > either execution speed or object creation (less object creation is > generally > better). There is no point in using it in a case like this. Inject is > whiz-bang cool, and sometimes seems like an elegant solution, but it > usually > makes code slower and harder to read when people use it. > > > Kirk Haines > --0016e65aef4001adb9047974ffdb--