From: Ara.T.Howard@... Date: 2005-06-02T11:40:23+09:00 Subject: Re: Interesting discovery... On Wed, 1 Jun 2005, Austin Ziegler wrote: > On 5/31/05, Ara.T.Howard wrote: >> On Wed, 1 Jun 2005, Austin Ziegler wrote: >>> I had a user report a slowdown in PDF::Writer. I'm pretty certain I know >>> where the problem is, but I found something very interesting. About 3% of >>> the profiled performance of the manual generation (with Shugo Maeda's new >>> profiler) -- and near 20,000,000 (yes twenty MILLION) calls -- are calls >>> to Kernel.respond_to?. =20 A little digging later, and it looks like 98% >>> of these calls -- or more -- are in Marshal.dump. That's ... amazing. >> wow. can you confirm with somthing like > > I've done quite a bit of confirmation. Much of this has to do with the > unique nature of the object graph in PDF::Writer documents -- there's quite > a bit of depth to the object graph. > > I was originally investigating Transaction::Simple as the culprit of my > number of calls, but that didn't mesh with what I *did* find. My final test > was to do: > > def Kernel.respond_to?(*a) > puts caller[0] > old_respond_to(*a) > end > > After a few moments, I literally had tens of *thousands* of calls indicating > that the caller was Marshal.dump. > > My guess -- and I haven't looked at the Marshal.dump code to confirm -- is > that what's beeing looked for is a custom dumper, and that search is faster > than assuming the dumper is there (because in most cases, it won't be, I > don't think). great. thanks for the follow-up. i run into things like that alot and always wonder if calling a method and rescuing NoMethodError is slower or faster than checking with respond_to? harp:~ > cat a.rb require 'benchmark' class C def c; end def rescue_test n n.times do begin self.a rescue NoMethodError begin self.b rescue NoMethodError self.c end end end end def respond_to_test n n.times do if respond_to? 'a' self.a elsif respond_to? 'b' self.b else self.c end end end end c = C::new n = 2 ** 16 GC::disable Benchmark::bm do |b| %w(rescue_test respond_to_test).map{|m| b.report(m){c.send m,n}} end harp:~ > ruby a.rb user system total real rescue_test 2.940000 0.320000 3.260000 ( 3.264758) respond_to_test 0.160000 0.050000 0.210000 ( 0.208268) looks like respond_to? is indeed faster. cheers. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | My religion is very simple. My religion is kindness. | --Tenzin Gyatso ===============================================================================