Maybe some one has noticed that some optimizations have been added
into XRuby runtime. 0 or 1 argument method invocation has been
separated.
Array#first is an example. It has two cases: 0 argument and 1
argument. In original code, we distinguish these cases when method is
invoked. The code is like this:
if (argc == 0) {
...
} else if (argc == 1) {
...
}
But in fact, we know how many arguments we have when we invoke the
method. For instance, the code
ary.first 1
means the argument size is 1. So we can call 1 argument branch directly.
RubyNoOrOneArgMethod is created for this purpose. Invocation with 0
argument will call
RubyValue run(RubyValue receiver, RubyBlock block)
Invocation with 1 argument will call
RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block);
Here is the definition for Array#first in MethodFactory which can
generate wrapper for method.
c.defineMethod("first", factory.getMethod("first",
MethodFactory.NO_OR_ONE_ARG));
No argument version:
public RubyValue first() { ... }
1 argument version:
public RubyValue first(RubyValue v) { ... }
Here is a test script for Array#first.
ary = [1, 2, 3, 4, 5, 6]
start_time = Time.new.to_f
1000000.times {
ary.first 1
}
end_time = Time.now.to_f
puts end_time - start_time
Test result are
trunk: 0.28
0.2.1: 0.45
As we have seen, the performance for 1 argument gets some improvements.
You can view code to know more details.
Ye Zheng
--
Everything is simple!