From: Dominik Bathon Date: 2005-10-28T02:45:24+09:00 Subject: Re: [SUMMARY] Ducksay (#52) On Thu, 27 Oct 2005 17:55:04 +0200, James Edward Gray II wrote: > On Oct 27, 2005, at 10:48 AM, Pit Capitain wrote: > >> Ruby Quiz schrieb: >> >>> class String >>> def width >>> inject(0) {|w, line| [w, line.chomp.size].max } >>> end >>> end >>> I just know I would have written width() as: >>> map { |line| line.chomp.size }.max >>> Dave's is more efficient though. It only ever keeps the highest >>> number, instead >>> of building an Array of all the lengths. Just one more reason >>> inject() is the >>> one iterator to rule them all. Thanks for trick #562, Dave! >>> >> >> I'm not sure about the efficiency. The inject() version builds a new >> array on each pass, whereas the map() version builds only one array. >> Even an inject() implementation without the arrays was running slower >> than the map() implementation on my computer. inject() is nice, but it >> definitely doesn't rule them all (sorry Robert :-). > > I didn't make that very clear. > > I was speaking of memory consumption. map() has to copy the whole > Array, while inject() does not. I'm not sure what you mean with "copy the whole array". The Enumerable#map implementation just creates an empty array and adds all elements that the block returns to it. One could argue that this leads to one big array (which still just contains Fixnums), while the arrays generated by the inject version can be garbage collected. But the inject version still allocates more memory overall. And the map version is really faster: require "benchmark" include Benchmark str = IO.read(ARGV.shift) class String def width1 inject(0) { |w, line| [w, line.chomp.size].max } end def width2 map { |line| line.chomp.size }.max end def t1 each { |line| [0, line.chomp.size] } end def t2 each { |line| line.chomp.size } end end bmbm(4) { |x| x.report("w1") { str.width1 } x.report("w2") { str.width2 } x.report("t1") { str.t1 } x.report("t2") { str.t2 } } $ ruby str_width_bm.rb /usr/share/dict/words Rehearsal --------------------------------------- w1 1.200000 0.000000 1.200000 ( 1.234289) w2 0.790000 0.010000 0.800000 ( 0.797576) t1 0.960000 0.000000 0.960000 ( 1.014776) t2 0.730000 0.010000 0.740000 ( 0.744466) ------------------------------ total: 3.700000sec user system total real w1 1.190000 0.010000 1.200000 ( 1.231020) w2 0.800000 0.000000 0.800000 ( 0.809417) t1 0.550000 0.000000 0.550000 ( 0.556069) t2 0.460000 0.010000 0.470000 ( 0.500228) Dominik