I was wondering if anyone had taken a look at what % of time that ruby
spends doing method dispatch?
I’ll eventually do the experiments myself, but I wanted to check with
y’all to see if someone had already done some investigations. It would
be an interesting experiment to see how much you can improve method
dispatch performance by caching the reference to the method call
target, and invalidating it when the call context changes.
Thanks,
-John
On Aug 17, 2006, at 5:05 PM, John L. wrote:
I’ll eventually do the experiments myself, but I wanted to check with
y’all to see if someone had already done some investigations. It would
be an interesting experiment to see how much you can improve method
dispatch performance by caching the reference to the method call
target, and invalidating it when the call context changes.
I’m not an internals expert, but I think the difficulty in optimizing
Ruby
method dispatch is that the result of a dispatch is not determined
by the local context but instead is determined by the state of all
the module objects searched during method dispatch:
singleton class
class and super classes
included modules in all of the above
Gary W.
I’d be interested in doing some experiments with DynamicMethods in the
CLR to see what kind of performance gains can happen with method
dispatch. And direct method dispatch in the CLR is very fast, if we
consider that each parameter is a boxed object reference (4 bytes) and
the actuall call is a call indirect instruction. Dealing with closures
is a bit more problematic though, and making that go fast could be
difficult.
It’s also fairly straightforward to substitute one dynamic method for
another one when a cache invalidation event occurs. It would be very
interesting to study the existing implementation’s method cache to see
what the triggers for cache invalidation look like …
Thanks for the input!
-John
On Fri, Aug 18, 2006 at 06:05:12AM +0900, John L. wrote:
I was wondering if anyone had taken a look at what % of time that ruby
spends doing method dispatch?
I’ll eventually do the experiments myself, but I wanted to check with
y’all to see if someone had already done some investigations. It would
be an interesting experiment to see how much you can improve method
dispatch performance by caching the reference to the method call
target, and invalidating it when the call context changes.
The current implementation has a method cache whose hit rate is above
95% or
so (don’t remember the exact figure; it’s not hard to reproduce anyway)
full method lookups are relatively rare.
Method dispatching is still fairly slow, though; I once measured that it
took
some ~200 instructions to run a CFUNC, and about half as much with YARV.
Last time I read YARV’s sources, it didn’t have inline method caches
(but it
was caching constants, IIRC), but it’s been a while and they might have
been
implemented meanwhile.
Mauricio F. wrote:
The current implementation has a method cache whose hit rate is above 95% or
so (don’t remember the exact figure; it’s not hard to reproduce anyway) —
full method lookups are relatively rare.
Method dispatching is still fairly slow, though; I once measured that it took
some ~200 instructions to run a CFUNC, and about half as much with YARV.
Last time I read YARV’s sources, it didn’t have inline method caches (but it
was caching constants, IIRC), but it’s been a while and they might have been
implemented meanwhile.
I’m about to re-post my profiling of Ruby on a moderate-sized “Matrix”
benchmark. I’ll post the link as soon as I get it re-run.
Hi,
On Thu, 17 Aug 2006 23:05:12 +0200, John L. [email protected] wrote:
I was wondering if anyone had taken a look at what % of time that ruby
spends doing method dispatch?
Here are some numbers. Running this code:
max = 2000
z = x = 0
while (x+=1) <= max
y = 0
while (y+=1) <= max
z = (x+y-z) % 32000
end
end
takes about 5.5s in plain Ruby 1.8.4 (on my machine).
Compiling it with Ruby2CExtension (latest version, all optimizations
turned on) and then running it takes about 0.9s.
One of the optimizations is to bypass rb_call and calling the C
functions
of those methods (almost) directly (when possible).
If this optimization is turned off then running the compiled code takes
about 3.1s. These additional 2.2s are all spent for method dispatch.
Plain Ruby spends at least the same time for method dispatch, so Ruby
spends at least 40% of the time doing method dispatch (in this case).
I hope that helps,
Dominik
M. Edward (Ed) Borasky wrote:
The current implementation has a method cache whose hit rate is above 95% or
benchmark. I’ll post the link as soon as I get it re-run.
All done and uploaded … the link is
http://rubyforge.org/cgi-bin/viewvc.cgi/MatrixBenchmark/?root=cougar
I re-ran this in single-user mode, so there is little interference from
X, etc.
M. Edward (Ed) Borasky wrote:
All done and uploaded … the link is
http://rubyforge.org/cgi-bin/viewvc.cgi/MatrixBenchmark/?root=cougar
I re-ran this in single-user mode, so there is little interference from
X, etc.
Updated over the weekend. YARV is about four times as fast as Ruby
1.8.5! I’ll probably rerun the profiling using “oprofile”, though.
“gprof” seems to have too low a sampling frequency to determine what’s
really going on with “reasonable” run times – 1 to 10 minutes.
Hi,
Mauricio F. wrote:
Method dispatching is still fairly slow, though; I once measured that it took
some ~200 instructions to run a CFUNC, and about half as much with YARV.
Last time I read YARV’s sources, it didn’t have inline method caches (but it
was caching constants, IIRC), but it’s been a while and they might have been
implemented meanwhile.
YARV already has inline method cache (see vm.c).