Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > I rock.

Reply
Thread Tools

I rock.

 
 
Eric Hodel
Guest
Posts: n/a
 
      05-03-2005
Yup, rb_intern needs to be cached. Yup, the __self thing is wrong (it
was late, and I forgot about NODE_SELF). No, it doesn't let you
directly call C code either (yet?).

$ cat demo/factorial.rb
class F
def factorial(n)
f = 1
n.downto(2) { |x| f *= x }
return f
end

def main # horrid but funny hack
return factorial(5)
end
end
$ ./translate2.rb demo/factorial.rb > f.c
$ cc -dynamic -bundle -undefined suppress -flat_namespace -g -O2 -pipe
-fno-common -I /usr/local/lib/ruby/1.8/powerpc-darwin7.9.0 f.c -o
F.bundle
$ ruby -I. -rF -e 'p F.new.factorial(5)'
120
$ time ruby -Idemo -rfactorial -e 'p F.new.factorial(9999)' > /dev/null

real 0m3.938s
user 0m3.360s
sys 0m0.080s
$ time ruby -I. -rF -e 'p F.new.factorial(9999)' > /dev/null

real 0m3.751s
user 0m3.340s
sys 0m0.060s

(but I don't expect a speed increase, the way it works)

$ cat f.c
// BEGIN METARUBY PREAMBLE
#include <ruby.h>
#define case_equal_long(x, y) (rb_funcall((x), rb_intern("==="), 1,
(y)))
// END METARUBY PREAMBLE
// class F < Object

static VALUE
rrc_cF_factorial(VALUE __self, VALUE n) {
VALUE f;
VALUE x;
f = LONG2FIX(1);
x = n;
while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) {
f = rb_funcall(f, rb_intern("*"), 1, x);
x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1));
};
return f;
}

static VALUE
rrc_cF_main(VALUE __self) {
return rb_funcall(__self, rb_intern("factorial"), 1, LONG2FIX(5));
}

void
Init_F() {
VALUE rrc_cF = rb_define_class("F", rb_path2class("Object"));

rb_define_method(rrc_cF, "factorial", rrc_cF_factorial, 1);
rb_define_method(rrc_cF, "main", rrc_cF_main, 0);

}

--
Eric Hodel - - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04



 
Reply With Quote
 
 
 
 
Phil Tomson
Guest
Posts: n/a
 
      05-03-2005
In article <>,
Eric Hodel <> wrote:
>Yup, rb_intern needs to be cached. Yup, the __self thing is wrong (it
>was late, and I forgot about NODE_SELF). No, it doesn't let you
>directly call C code either (yet?).
>
>$ cat demo/factorial.rb
>class F
> def factorial(n)
> f = 1
> n.downto(2) { |x| f *= x }
> return f
> end
>
> def main # horrid but funny hack
> return factorial(5)
> end
>end
>$ ./translate2.rb demo/factorial.rb > f.c
>$ cc -dynamic -bundle -undefined suppress -flat_namespace -g -O2 -pipe
>-fno-common -I /usr/local/lib/ruby/1.8/powerpc-darwin7.9.0 f.c -o
>F.bundle
>$ ruby -I. -rF -e 'p F.new.factorial(5)'
>120
>$ time ruby -Idemo -rfactorial -e 'p F.new.factorial(9999)' > /dev/null
>
>real 0m3.938s
>user 0m3.360s
>sys 0m0.080s
>$ time ruby -I. -rF -e 'p F.new.factorial(9999)' > /dev/null
>
>real 0m3.751s
>user 0m3.340s
>sys 0m0.060s
>
>(but I don't expect a speed increase, the way it works)
>
>$ cat f.c
>// BEGIN METARUBY PREAMBLE
>#include <ruby.h>
>#define case_equal_long(x, y) (rb_funcall((x), rb_intern("==="), 1,
>(y)))
>// END METARUBY PREAMBLE
>// class F < Object
>
>static VALUE
>rrc_cF_factorial(VALUE __self, VALUE n) {
>VALUE f;
>VALUE x;
>f = LONG2FIX(1);
>x = n;
>while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) {
>f = rb_funcall(f, rb_intern("*"), 1, x);
>x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1));
>};
>return f;
>}
>
>static VALUE
>rrc_cF_main(VALUE __self) {
>return rb_funcall(__self, rb_intern("factorial"), 1, LONG2FIX(5));
>}
>
>void
>Init_F() {
>VALUE rrc_cF = rb_define_class("F", rb_path2class("Object"));
>
>rb_define_method(rrc_cF, "factorial", rrc_cF_factorial, 1);
>rb_define_method(rrc_cF, "main", rrc_cF_main, 0);
>
>}
>



How does this differ from the current RubyToC stuff?
Is this newer version available for download yet?

Phil
 
Reply With Quote
 
 
 
 
Eric Hodel
Guest
Posts: n/a
 
      05-03-2005
On 03 May 2005, at 11:09, Phil Tomson wrote:

> In article <>,
> Eric Hodel <> wrote:
>> $ cat f.c
>> // BEGIN METARUBY PREAMBLE
>> #include <ruby.h>
>> #define case_equal_long(x, y) (rb_funcall((x), rb_intern("==="), 1,
>> (y)))
>> // END METARUBY PREAMBLE
>> // class F < Object
>>
>> static VALUE
>> rrc_cF_factorial(VALUE __self, VALUE n) {
>> VALUE f;
>> VALUE x;
>> f = LONG2FIX(1);
>> x = n;
>> while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) {
>> f = rb_funcall(f, rb_intern("*"), 1, x);
>> x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1));
>> };
>> return f;
>> }
>>
>> static VALUE
>> rrc_cF_main(VALUE __self) {
>> return rb_funcall(__self, rb_intern("factorial"), 1, LONG2FIX(5));
>> }
>>
>> void
>> Init_F() {
>> VALUE rrc_cF = rb_define_class("F", rb_path2class("Object"));
>>
>> rb_define_method(rrc_cF, "factorial", rrc_cF_factorial, 1);
>> rb_define_method(rrc_cF, "main", rrc_cF_main, 0);
>>
>> }
>>

>
>
> How does this differ from the current RubyToC stuff?


This one (Ruby2RubyC) generates a C extension, where the other tail
generates raw, type inferenced C code.

I think Ruby2RubyC can make optimizations for Fixnum math and other
boolean logic, but I haven't explored that yet.

Ruby2RubyC is also dynamic code safe. It automatically converts from
Fixnum to Bignum, thanks to the Ruby C runtime. (I snipped the output
of factorial(9999), but it outputs a handful of lines of numbers.)

For example, the other tail could not handle factorial(9999) because C
doesn't have Bignums.

> Is this newer version available for download yet?


No, not yet. Maybe after Thursday hacking.

--
Eric Hodel - - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04



 
Reply With Quote
 
Linus Sellberg
Guest
Posts: n/a
 
      05-03-2005
> This one (Ruby2RubyC) generates a C extension, where the other tail
> generates raw, type inferenced C code.


Sounds like a nice way to obfuscate code a bit, for those that are
inclined that way.



 
Reply With Quote
 
Gyoung-Yoon Noh
Guest
Posts: n/a
 
      05-03-2005
On 5/4/05, Eric Hodel <> wrote:
> On 03 May 2005, at 11:09, Phil Tomson wrote:
>
> > In article <>,
> > Eric Hodel <> wrote:
> >> $ cat f.c
> >> // BEGIN METARUBY PREAMBLE
> >> #include <ruby.h>
> >> #define case_equal_long(x, y) (rb_funcall((x), rb_intern("==="), 1,
> >> (y)))
> >> // END METARUBY PREAMBLE
> >> // class F < Object
> >>
> >> static VALUE
> >> rrc_cF_factorial(VALUE __self, VALUE n) {
> >> VALUE f;
> >> VALUE x;
> >> f = LONG2FIX(1);
> >> x = n;
> >> while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) {
> >> f = rb_funcall(f, rb_intern("*"), 1, x);
> >> x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1));
> >> };
> >> return f;
> >> }
> >>
> >> static VALUE
> >> rrc_cF_main(VALUE __self) {
> >> return rb_funcall(__self, rb_intern("factorial"), 1, LONG2FIX(5));
> >> }
> >>
> >> void
> >> Init_F() {
> >> VALUE rrc_cF = rb_define_class("F", rb_path2class("Object"));
> >>
> >> rb_define_method(rrc_cF, "factorial", rrc_cF_factorial, 1);
> >> rb_define_method(rrc_cF, "main", rrc_cF_main, 0);
> >>
> >> }
> >>

> >
> >
> > How does this differ from the current RubyToC stuff?

>
> This one (Ruby2RubyC) generates a C extension, where the other tail
> generates raw, type inferenced C code.
>
> I think Ruby2RubyC can make optimizations for Fixnum math and other
> boolean logic, but I haven't explored that yet.
>
> Ruby2RubyC is also dynamic code safe. It automatically converts from
> Fixnum to Bignum, thanks to the Ruby C runtime. (I snipped the output
> of factorial(9999), but it outputs a handful of lines of numbers.)
>
> For example, the other tail could not handle factorial(9999) because C
> doesn't have Bignums.
>
> > Is this newer version available for download yet?

>
> No, not yet. Maybe after Thursday hacking.
>
> --
> Eric Hodel - - http://segment7.net
> FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
>
>


Python has PyRex which enables writing CPython extensions
with python-like syntax. I guess Ruby2RubyC can do a foundation
role for future great works such as writing extensions with ruby
syntax, enhancing performance easily with type conversion,
or can be used as intermediate format for translating Ruby to C.

Cheers,

--
http://nohmad.sub-port.net



 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      05-03-2005

On May 3, 2005, at 10:23 AM, Eric Hodel wrote:

> Yup, rb_intern needs to be cached. Yup, the __self thing is wrong (it
> was late, and I forgot about NODE_SELF). No, it doesn't let you
> directly call C code either (yet?).

...
> $ cat f.c
> ...
> static VALUE
> rrc_cF_factorial(VALUE __self, VALUE n) {
> VALUE f;
> VALUE x;
> f = LONG2FIX(1);
> x = n;
> while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) {
> f = rb_funcall(f, rb_intern("*"), 1, x);
> x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1));
> };
> return f;


YAY! You do rock! And no, "__self" doesn't suck, but most of the C impl
I've seen just calls it "self" straight up. This is really cool and I
can't wait to read the code.



 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      05-03-2005

On May 3, 2005, at 1:32 PM, Gyoung-Yoon Noh wrote:

> Python has PyRex which enables writing CPython extensions
> with python-like syntax. I guess Ruby2RubyC can do a foundation
> role for future great works such as writing extensions with ruby
> syntax, enhancing performance easily with type conversion,
> or can be used as intermediate format for translating Ruby to C.


Ruby2RubyC will probably not, for the first few months at least,
improve performance with any sort of type conversion at all. In fact, I
suspect that Eric's current version will start to get fairly severe
penalties until we move away from using rb_funcall for everything. If
you want performance then you should either hand write (using
RubyInline!) or take a peek at zenoptimizer when it gets released in my
ZenHacks package (it uses a combination of ruby2c and rubyinline with a
custom lightweight profiler I wrote last week).

--
ryand- - Seattle.rb -
http://www.zenspider.com/seattle.rb
http://blog.zenspider.com/ - http://rubyforge.org/projects/ruby2c



 
Reply With Quote
 
Eric Hodel
Guest
Posts: n/a
 
      05-03-2005
On 03 May 2005, at 15:21, Ryan Davis wrote:

> On May 3, 2005, at 1:32 PM, Gyoung-Yoon Noh wrote:
>
>> Python has PyRex which enables writing CPython extensions
>> with python-like syntax. I guess Ruby2RubyC can do a foundation
>> role for future great works such as writing extensions with ruby
>> syntax, enhancing performance easily with type conversion,
>> or can be used as intermediate format for translating Ruby to C.

>
> Ruby2RubyC will probably not, for the first few months at least,
> improve performance with any sort of type conversion at all. In fact,
> I suspect that Eric's current version will start to get fairly severe
> penalties until we move away from using rb_funcall for everything.


Yup, it only bypasses the fast parts of eval.c (AST walking), and none
of the slow parts (rb_funcall) so you get almost zero speed benefit out
of it currently. (See the "time factorial(9999)" output further up the
thread).

> If you want performance then you should either hand write (using
> RubyInline!) or take a peek at zenoptimizer when it gets released in
> my ZenHacks package (it uses a combination of ruby2c and rubyinline
> with a custom lightweight profiler I wrote last week).


Yes. When you find a slow part, you could use this as your template.
You'll have working Ruby/C code to refactor into faster C code in no
time at all.

I should be able to skip rb_funcall for places where I know the types,
and directly call the C implementation of a method. That will be more
work though, because I'll have to fall back in case a TypeError is
raised in addition to pulling the right bits from the VALUE.

Or something.

--
Eric Hodel - - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04



 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      05-03-2005

On May 3, 2005, at 3:45 PM, Eric Hodel wrote:

> On 03 May 2005, at 15:21, Ryan Davis wrote:
>
>> If you want performance then you should either hand write (using
>> RubyInline!) or take a peek at zenoptimizer when it gets released in
>> my ZenHacks package (it uses a combination of ruby2c and rubyinline
>> with a custom lightweight profiler I wrote last week).

>
> Yes. When you find a slow part, you could use this as your template.
> You'll have working Ruby/C code to refactor into faster C code in no
> time at all.


oooh. I didn't think of that. Not sure why.

> I should be able to skip rb_funcall for places where I know the types,
> and directly call the C implementation of a method. That will be more
> work though, because I'll have to fall back in case a TypeError is
> raised in addition to pulling the right bits from the VALUE.


*nod*

I expect that we'll do a version down the line that includes
TypeChecker in the SexpProcessor pipeline and we'll have better sends
in that version.

Isn't it cool that we have these discussions out on a public list like
ruby-talk??? It is almost like, oh I dunno, we want people to look at
the software!

--
ryand- - Seattle.rb -
http://www.zenspider.com/seattle.rb
http://blog.zenspider.com/ - http://rubyforge.org/projects/ruby2c



 
Reply With Quote
 
Gyoung-Yoon Noh
Guest
Posts: n/a
 
      05-04-2005
On 5/4/05, Eric Hodel <> wrote:
> On 03 May 2005, at 15:21, Ryan Davis wrote:
>
> > On May 3, 2005, at 1:32 PM, Gyoung-Yoon Noh wrote:
> >
> >> Python has PyRex which enables writing CPython extensions
> >> with python-like syntax. I guess Ruby2RubyC can do a foundation
> >> role for future great works such as writing extensions with ruby
> >> syntax, enhancing performance easily with type conversion,
> >> or can be used as intermediate format for translating Ruby to C.

> >
> > Ruby2RubyC will probably not, for the first few months at least,
> > improve performance with any sort of type conversion at all. In fact,
> > I suspect that Eric's current version will start to get fairly severe
> > penalties until we move away from using rb_funcall for everything.

>
> Yup, it only bypasses the fast parts of eval.c (AST walking), and none
> of the slow parts (rb_funcall) so you get almost zero speed benefit out
> of it currently. (See the "time factorial(9999)" output further up the
> thread).



Oops, by 'type conversion', I meant PyRex-style C types usage.
PyRex enables feeding native C types, instead of PythonC types,
easily within its python-like syntax anywhere. In case of ruby, I think
it will be much greater if it's possible to use RubyDL's type wrapper
against native C types.

--
http://nohmad.sub-port.net



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57