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.
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 Wright
···
On Aug 17, 2006, at 5:05 PM, John Lam 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.
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.
···
On Fri, Aug 18, 2006 at 06:05:12AM +0900, John Lam 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.
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 8/17/06, Mauricio Fernandez <mfp@acm.org> wrote:
On Fri, Aug 18, 2006 at 06:05:12AM +0900, John Lam 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.
On Fri, Aug 18, 2006 at 06:05:12AM +0900, John Lam 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.
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.
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 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.
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.
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.