On Feb 20, 2008, at 15:12 , MenTaLguY wrote: > # of iterations = 1000000 > user system total real > null_time 0.218000 0.000000 0.218000 ( 0.219000) > split/each/<<+ 24.516000 0.140000 24.656000 ( 24.703000) > split/map/<<+ 26.109000 0.172000 26.281000 ( 26.281000) > split/inject/<<+ 30.797000 0.172000 30.969000 ( 31.000000) > > Being an FP nut used to using folds, I'm always a little annoyed that > inject fares so poorly in these things; mainly we're just lacking a > C implementation of Array#inject. coming back to this point... what do you mean by we're missing a C impl of Array#inject? Granted, the impl is on Enumerable, but I wouldn't think it would make THAT much of a difference... But I try my best not to speculate (ever), so... (my C coding skills absolutely suck these days, please point out improvements) #!/usr/bin/env ruby -w require 'benchmark' require 'ipaddr' $: << File.expand_path("~/Work/p4/zss/src/RubyInline/dev/lib") require 'inline' class Array inline do |builder| builder.c_raw <<-EOF VALUE new_inject(int argc, VALUE *argv, VALUE self) { long max = RARRAY(self)->len; long i = argc ? 0 : 1; VALUE memo = argc ? argv[0] : RARRAY(self)->ptr[0]; for (i; i < max; i++) { memo = rb_yield_values(2, memo, RARRAY(self)->ptr[i]); } return memo; } EOF end end p "127.0.0.1".split('.').inject(0) { |s,n| (s << 8) + n.to_i } p "127.0.0.1".split('.').new_inject(0) { |s,n| (s << 8) + n.to_i } max = (ARGV.shift || 1_000_000).to_i # # of iterations = 1000000 # user system total real # null_time 0.130000 0.000000 0.130000 ( 0.129965) # split/each/<< 10.940000 0.010000 10.950000 ( 10.968329) # split/inject/<< 15.280000 0.020000 15.300000 ( 15.330062) # split/new_inject/<< 15.020000 0.070000 15.090000 ( 15.629343) puts "# of iterations = #{max}" Benchmark::bm(22) do |x| x.report("null_time") do for i in 0..max do # do nothing end end x.report("split/each/<<") do for i in 0..max do ip = 0 "127.0.0.1".split('.').each { |n| ip = (ip << 8) + n.to_i } ip end end x.report("split/inject/<<") do for i in 0..max do "127.0.0.1".split('.').inject(0) { |s,n| (s << 8) + n.to_i } end end x.report("split/new_inject/<<") do for i in 0..max do "127.0.0.1".split('.').new_inject(0) { |s,n| (s << 8) + n.to_i } end end end