From: Ryan Davis Date: 2002-09-20T10:05:51+09:00 Subject: [MATZ] Re: ruby-inline and alias_method On Thursday, September 19, 2002, at 05:54 PM, Joseph McDonald wrote: > I have be experimenting with Ruby-Inline, and I have to say it is > super cool. I have run into a problem that is either a problem in my > code (likely), or a problem with inline, or perhaps a problem with > ruby. The problem is that when I access an inlined method that has > been aliased, it slows down 100 fold. below is an example that just > sums the elements of an array. I also run it without using the alias > and it runs fast (about 9 times as fast as ruby native). I also > include at the bottom the code that Ruby-Inline generated. Matz or other extern/ruby gurus: I'm reasonably sure that it's not RubyInline that is causing this problem. I'm still not sure what is, but it seems to be centered around the following line: Array.send(:alias_method, :thesum, meth.intern) If he runs the benchmark w/o this madness, then the inlined C code is 9x faster than the ruby code. > #!/usr/local/bin/ruby > require 'RubyInline-1.0.5/inline' > > class Array > include Inline > > def sum(*args) > inline args, <<-'END' > int len, result = 0; > int j; > VALUE *arr; > > arr = RARRAY(self)->ptr; > len = RARRAY(self)->len; > for(j=0; j result += FIX2INT(arr[j]); > } > return INT2FIX(result); > END > end > > def slowsum > result = 0 > each { |x| result += x } > result; > end > end > > iters = 100000 > methods = ['slowsum','sum'] > > methods.each do |meth| > Array.send(:alias_method, :thesum, meth.intern) > > tstart = Time.now > iters.times do > [0,1,2,3,4,5,6,7,8,9,10].thesum > end > tend = Time.now > total = tend - tstart > avg = total / iters > > printf "Type = #{meth}, Iter = #{iters}, time = %.8f sec, %.8f sec > / iter\n", total, avg > end > > # now check this without the aliased version > tstart = Time.now > iters.times do > [0,1,2,3,4,5,6,7,8,9,10].sum > end > tend = Time.now > total = tend - tstart > avg = total / iters > > printf "Type = normal sum (no alias), Iter = #{iters}, time = %.8f > sec, %.8f sec / iter\n", total, avg > > exit > > #-------------- > The code that was generated by inline is: > > > #include "ruby.h" > > static VALUE t_sum(int argc, VALUE *argv, VALUE self) { > int len, result = 0; > int j; > VALUE *arr; > > arr = RARRAY(self)->ptr; > len = RARRAY(self)->len; > for(j=0; j result += FIX2INT(arr[j]); > } > return INT2FIX(result); > > } > > VALUE cMod_Array_sum; > > void Init_Mod_Array_sum() { > cMod_Array_sum = rb_define_module("Mod_Array_sum"); > rb_define_method(cMod_Array_sum, "_sum", t_sum, -1); > } > > > #-------------- > The output of the program was: > > Type = slowsum, Iter = 100000, time = 1.36584400 sec, 0.00001366 sec / > iter > Type = sum, Iter = 100000, time = 16.48371500 sec, 0.00016484 sec / > iter > Type = normal sum (no alias), Iter = 100000, time = 0.14434800 sec, > 0.00000144 sec / iter > > thanks, > -joe >