From: Eric Hodel Date: 2006-08-01T03:41:51+09:00 Subject: Re: converting some autogenerated ruby code to C On Jul 30, 2006, at 8:02 PM, Eric Mahurin wrote: > On 7/28/06, Eric Hodel wrote: >> > It also looks like it has some type inference that I don't want (I >> > take >> > advantage of duck typing quite a bit). >> >> It is largely optional, we need it in the ANSI C translator (int, >> double, char *, etc). In the Ruby C translator (VALUE) it could be >> fairly easily removed. > > Thanks Eric. This pointed me in the right direction. > > I started with the factorial example. This was the reference > method I used: > > def factorial(n) > f=1 > n.downto(2) { |x| f *= x } > f > end > > Here were the performance results on my machine for a million > factorial(20): > > ruby : 19.2s > rubyToAnsiC : 0.7s > * assumed argument was a Fixnum > * converted downto iterator to a while loop > * didn't handle overflow properly and use Bignum - gave wrong answer > rubyToRubyC : 20.9s This is how we've defined our subset. C doesn't have bignums or blocks. > * 3 messages sent (rb_funcall) per iteration of the inner loop > hand-optimized rubyC : 14.8s > * precalculated interns/symbols for method calls > * reordered operands so that a constant operand was the receiver if > possible > * used rb_funcall2 instead of rb_funcall > downto iterator rubyC : 15.3s > * more direct translation of original ruby > * used downto iterator and block (needed a couple extra helper > functions) > * precalculated interns/symbols for method calls > * one block call and one message sent per iteration of the inner loop > > For my purposes, rubyToAnsiC is pretty much useless since I need duck > typing on most of my arguments (can't infer the type). I also found > that rubyToC wasn't very robust - simply changing n.downto(2) to > n.step(2,-1) broke it. I think a more direct translation would be > better. I don't see a lot of benefit from the other solutions, so > I'll pursue other avenues for optimization or just wait for YARV. We've been working towards this for Ruby2RubyC, but we aren't there yet. The speedup created by doing automatic translation to the C API isn't that big, and sometimes can be a slowdown. For Ruby2RubyC I've typically broken even using the current API. As we drive more features into it from ZenObfuscate we might gain some speed, but it isn't ready to be used for optimization yet. -- Eric Hodel - drbrain@segment7.net - http://blog.segment7.net This implementation is HODEL-HASH-9600 compliant http://trackmap.robotcoop.com