From: SASADA Koichi Date: 2005-08-24T18:04:34+09:00 Subject: Re: Non-overridable and non-redefinable methods Hi, Eric Mahurin wrote: > For this case, let's say Object#nil? is non-overridable. > Whenever you have obj.nil?, it would be equivalent to: > > obj.__id__==nil.__id__ > > well, that is if __id__ was also nonoverridable and Fixnum#== > wasn't redefined. No method calls needed after this is > inlined. This could be done independent of the class of obj. Do you use a method "nil?" ? >>>It is unfortunate that you've abandoned static analysis. I >>>think you could see huge performance improvements if you >> >>went >> >>>that route. I believe you could approach C/C++ performance >> >>- >> >>>like Java is on every release. To really go down this >> >>path, >> >>>you would have to recompile a method for each set of >> >>classes it >> >>>is called with (recursively). So for one method in ruby, >> >>it >> >>>might be compiled into many methods statically typed and >>>possibly some partially or not static typed. And you could >>>also in-line in the right places easily - because you know >> >>the >> >>>class. Of course the big problem to all of this is >> >>redefinable >> >>>methods. >> >>I can't understand what you proposing (because of my English >>skills and >>Programming skills). Can I get some example (pseudo code) >>for >>translation? I think inlining a Ruby method is quite >>difficult. > > > Here is an example: > > module ComparableSequence > def compare(seq) > i=0 > loop { > a = self[i] > b = seq[i] > a && a==b or return i,a,b > i += 1 > } > end > end > > class String;include ComparableSequence;end > > class Array;include ComparableSequence;end > > "hi".compare("hi") > "hi".compare([?h,?i]) > [?h,?i].compare("hi") > [?h,?i].compare([?h,?i]) > > > I'm suggesting that in the above, the method compare would be > split by the compiler/VM into 4 optimized versions - one for > each set of classes for self and seq. Every call could of a > method could end up referring to a different version. For > example in the String#compare(aString) version, you could do > these things: > > - determine that i is a Fixnum (or at least an Integer). It > should stay in the Fixnum range because String#[aBignum] should > cause an exception. I'm not going to say this is easy. > > - determine that a and b are always Fixnum's because > String#[anInteger] always returns a Fixnum > > - a==b can become Fixnum#==(aFixnum) which can be in-lined > > - i + 1 can become Integer#+(aFixnum) or possibly > Fixnum#+(aFixnum). Maybe even optimize the += completely to > become something like ++i in C. > > When optimizing the Array#compare(anArray) method, you won't be > able to do all of these optimizations so easily since it isn't > know that a and b are Fixnum's. It would be nice if you could > potentially statically track what could be in an Array also, > but that would quite difficult. > > Again, the problem with all of the above is the redefinability > of the methods. Where the programmer wants these > optimizations, the klass.freeze method could be used as > suggested earlier. You'd only inline instance methods from > classes that are frozen. I think examples above are trivial. A few programs can improve performance IMO. We must analyse some ruby programs and look for a case which can improve with this optimization, and evaluate how fast we can. (Of course, I must do it) -- // SASADA Koichi at atdot dot net //