Percentage of time spent in method dispatch?


J

John Lam

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
http://www.iunknown.com
 
Ad

Advertisements

G

gwtmp01

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
 
M

Mauricio Fernandez

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.
 
J

John Lam

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
http://www.iunknown.com
 
M

M. Edward (Ed) Borasky

Mauricio said:
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.
 
D

Dominik Bathon

Hi,

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 =3D 2000
z =3D x =3D 0
while (x+=3D1) <=3D max
y =3D 0
while (y+=3D1) <=3D max
z =3D (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 function=
s =

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
 
Ad

Advertisements

S

SASADA Koichi

Hi,

Mauricio said:
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).
 
Ad

Advertisements

M

M. Edward (Ed) Borasky

M. Edward (Ed) Borasky said:
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.
 

Top