From: redstun Date: 2011-01-28T00:10:41+09:00 Subject: Re: Enumerable.inject_with_index? --001485f8753691cdc8049ad55967 Content-Type: text/plain; charset=UTF-8 guess we find a spot to improve when chaining up multiple enum methods? btw, looks like you guys both have more powerful computer than mine. ;-) On Thu, Jan 27, 2011 at 9:10 PM, Benoit Daloze wrote: > On 27 January 2011 01:42, redstun wrote: > > Interesting, thanks Colin. > > > > As you said, the code you demonstrated, could performer better, meanwhile > > it's somewhat less elegant. > > > > IMHO the code is ok, we just have more space inside the > > interpreter/runtime to get improved, like in JVM, the JIT compiler could > > compile all of the 4 lines of code in to the same machine instructions > and > > yield the same performance. > > > > The dynamic nature and elegance design of Ruby certainly sacrificed > > performance at somewhat level, but that doesn't stop you and me from > using > > it, right? :-) > > > > Anyway, thanks for the benchmark demo, I just ran it on my machine, with > > both MRI and JRuby, > > MRI 1.8.7 > > user system total real > > each_with_index.inject(0) 4.930000 0.000000 4.930000 ( 5.036288) > > inject(0) 3.088000 0.000000 3.088000 ( 3.080176) > > each_with_index 2.668000 0.000000 2.668000 ( 2.668153) > > each 1.700000 0.000000 1.700000 ( 1.713098) > > > > JRuby 1.5.6 > > user system total real > > each_with_index.inject(0) 1.918000 0.000000 1.918000 ( 1.918000) > > inject(0) 1.058000 0.000000 1.058000 ( 1.058000) > > each_with_index 0.979000 0.000000 0.979000 ( 0.979000) > > each 0.624000 0.000000 0.624000 ( 0.624000) > > > > Like your result the raw each runs the fastest, but we can also find > that, > > the result of each_with_index.inject with JRuby is already close to that > of > > raw each with MRI. > > > > > > On Tue, Jan 25, 2011 at 5:43 AM, Colin Bartlett >wrote: > > > >> I'm curious as to when and why people use each_with_index and/or > >> inject, etc, instead of a somewhat less elegant, and admittedly > >> possibly less flexible, more direct approach. (Which usually(?) takes > >> about the same number of characters for the code.) > >> > >> ary = [3, 4, 5] > >> rrr = ary.each_with_index.inject(0) { |sum, (v, index)| sum + v * index > } > >> p rrr #=> 14 > >> index = -1; rrr = ary.inject(0) { |sum, v| index += 1; sum + v * index } > >> p rrr #=> 14 > >> rrr = 0; ary.each_with_index { |v, index| rrr += v * index }; rrr > >> p rrr #=> 14 > >> index = -1; rrr = 0; ary.each { |v| index += 1; rrr += v * index }; rrr > >> p rrr #=> 14 > >> > >> require "benchmark" > >> kt = 500_000 > >> Benchmark.bmbm() do |bm| > >> bm.report( "each_with_index.inject(0)" ) { kt.times { > >> rrr = ary.each_with_index.inject(0) { |sum, (v, index)| sum + v * > index } > >> } } > >> bm.report( "inject(0)" ) { kt.times { > >> index = -1; rrr = ary.inject(0) { |sum, v| index += 1; sum + v * index > } > >> } } > >> bm.report( "each_with_index" ) { kt.times { > >> rrr = 0; ary.each_with_index { |v, index| rrr += v * index } > >> } } > >> bm.report( "each" ) { kt.times { > >> index = -1; rrr = 0; ary.each { |v| index += 1; rrr += v * index } > >> } } > >> end > >> > >> #=> > >> Rehearsal ------------------------------------------------------------- > >> each_with_index.inject(0) 2.410000 0.000000 2.410000 ( 2.404242) > >> inject(0) 1.000000 0.000000 1.000000 ( 1.000677) > >> each_with_index 0.840000 0.010000 0.850000 ( 0.846287) > >> each 0.640000 0.000000 0.640000 ( 0.640142) > >> ---------------------------------------------------- total: 4.900000sec > >> > >> user system total real > >> each_with_index.inject(0) 2.380000 0.020000 2.400000 ( 2.392590) > >> inject(0) 1.000000 0.000000 1.000000 ( 0.999785) > >> each_with_index 0.850000 0.000000 0.850000 ( 0.846178) > >> each 0.640000 0.000000 0.640000 ( 0.639366) > >> > >> (My apologies if the benchmarks are ragged and unaligned.) > >> > >> > > > > Just to complete with 1.9 (ruby 1.9.3dev (2011-01-26 trunk 30659) > [x86_64-darwin10.6.0]) results: > > Rehearsal ------------------------------------------------------------- > each_with_index.inject(0) 1.220000 0.000000 1.220000 ( 1.220411) > inject(0) 0.560000 0.000000 0.560000 ( 0.568007) > each_with_index 0.510000 0.010000 0.520000 ( 0.516797) > each 0.400000 0.000000 0.400000 ( 0.405471) > ---------------------------------------------------- total: 2.700000sec > > user system total real > each_with_index.inject(0) 1.250000 0.000000 1.250000 ( 1.268727) > inject(0) 0.570000 0.010000 0.580000 ( 0.582921) > each_with_index 0.510000 0.000000 0.510000 ( 0.510591) > each 0.390000 0.000000 0.390000 ( 0.401833) > > Only each_with_index.inject is notably slower, others are similar. > > --001485f8753691cdc8049ad55967--