From: Kristof Bastiaensen Date: 2004-07-19T23:42:24+09:00 Subject: Re: Compiling Ruby code On Mon, 19 Jul 2004 13:54:53 +0200, Nospam wrote: > Hi, Hi > > > What I mean is, this... > > class Example > def example > puts "Hello World!" > end > end > > ... can also be written in C using the Ruby C API, am I right? So why > wouldn't it be possible to convert all Ruby code to C code using the > Ruby C API? Yes, that's possible, but depending on the C code you write, there isn't much performance gain. You can write any ruby code in C, but if you just convert it litteraly to C, there isn't much performance gain. For example when you write arr[1] = 2 #arr is an Array you could use rb_ary_store(arr, 1, INT2FIX(2)), but that wouldn't be equivalent to the ruby code. When the Array#[] method would change, the ruby code would see the change, but the C code wouldn't. The solution would be to use something like rb_funcall(arr, rb_intern("[]"), 0), but then there would be no performance benefit, because ruby still has to look up the method. The point is that it is possible to write more efficient ruby code in C, but it isn't really ruby code anymore. > > This would probably result in some performance gain (no need to parse > the code anymore at run-time), but for some people more important, you > can distribute your Ruby applications closed-source. In the future the > performance gain maybe could be increased by performing special > optimizations during the conversion process. > The parsing fase doesn't take so much performance, since it is only done at loading time. > Am I right on this, or do I forget something important which makes the > above quite hard to do? > > With kind regards, > > Peter Well, I do think it is possible to compile Ruby, but it would be to hard. Firstly eval and module_eval should be thrown away, because they need to be able to parse code at runtime. Continuations make compiling very messy, since the stack needs to be copied. This can also can cause troubles when interfacing with native c-calls. (I wonder how the current Ruby-interpreter manages this...) The best way is IMO to have a different language that resembles Ruby as much as possible, but allows it to be compiled easily. (I am sure Matz wouldn't allow Ruby to be crippled to allow compilation). It would have limitations that Ruby doesn't have (no eval or continuations), but it would be a nice alternative for coding in C. In fact code blocks and closures aren't that difficult to compile, and I think any decent compilable language should have them. As for Ruby, the best performance gain would be by using a Just-In-Time compiler. This way, the compiler can make assumptions about the code, and recompile when this assumptions are wrong. Take for example the following code: 5.times do { |i| puts i } Here the compiler could inline the code for times and produce very efficient code. The same goes for other standard library functions like Array#[], etc. However it is still possible to redefine Numeric#times (though I don't see a good reason to!). If the method would be redefined, then the just-in-time compiler could recompile it. The same goes for method arguments. When an argument to a method is always from the same class, the compiler can call the methods on that object directly (without lookup), or even inline them. However when different kinds of objects get passed to the method, then the JIT-compiler could recompile the method, so that it works with all objects. In this way the JIT can create well performing code, and at the same time keep the dynamic nature of Ruby. When methods are redefined, or added, the jit-compiler makes the changes. It would be nice to have such an interpreter, but it would be a considerable amount of work to implement it, as it would need a complete rewrite of the Ruby-interpreter. Regards, Kristof