Laurent Sansonetti
lsans****@apple*****
Fri Jun 8 16:24:11 JST 2007
I committed a working experiment as r1821! It automatically defines the method directly in C by generating Libffi closures. $ cat bench.rb require 'benchmark' require 'osx/foundation' def job ary = OSX::NSMutableArray.alloc.init str = OSX::NSString.stringWithString('foo') ary.addObject(str) num = OSX::NSNumber.numberWithInt(42) ary.addObject(num) count = ary.count ary.removeAllObjects end puts Benchmark.measure { 1000.times { job } } puts Benchmark.measure { 10_000.times { job } } puts Benchmark.measure { 100_000.times { job } } *** Old RubyCocoa *** $ ruby bench.rb 0.170000 0.000000 0.170000 ( 0.168513) 1.640000 0.010000 1.650000 ( 1.686002) 16.450000 0.080000 16.530000 ( 16.764010) $ ruby bench.rb 0.170000 0.000000 0.170000 ( 0.173943) 1.640000 0.010000 1.650000 ( 1.679036) 16.510000 0.100000 16.610000 ( 16.931537) *** New RubyCocoa *** $ ruby bench.rb 0.070000 0.000000 0.070000 ( 0.066736) 0.650000 0.000000 0.650000 ( 0.656822) 6.490000 0.040000 6.530000 ( 6.598461) $ ruby bench.rb 0.070000 0.000000 0.070000 ( 0.067404) 0.650000 0.000000 0.650000 ( 0.671378) 6.520000 0.040000 6.560000 ( 6.705908) In average ~3 times faster! All tests and samples are working on my environment. I will verify on other environments later. If you find something wrong please tell me. Laurent On Jun 6, 2007, at 11:56 AM, Laurent Sansonetti wrote: > After a quick investigation, it seems that #define_method is the > culprit. It's really slow when used with Proc. Using a regular eval to > add the method seems to be better. > > $ cat bench2.rb > require 'benchmark' > class Foo > def method_missing(*a); foo; end > def foo; end > end > Foo.class_eval { define_method(:foo2) { 0 } } > Foo.class_eval("def foo3; end") > n = 1_000_000 > Benchmark.bm(7) do |x| > o = Foo.new > x.report('method_missing') { n.times { o.missing } } > x.report('define_method') { n.times { o.foo2 } } > x.report('eval') { n.times { o.foo3 } } > x.report('regular') { n.times { o.foo } } > end > > $ ruby bench2.rb > user system total real > method_missing 1.030000 0.010000 1.040000 ( 1.081370) > define_method 0.730000 0.010000 0.740000 ( 0.773041) > eval 0.280000 0.000000 0.280000 ( 0.303355) > regular 0.280000 0.000000 0.280000 ( 0.296050) > > Laurent > > On Jun 5, 2007, at 5:47 PM, Laurent Sansonetti wrote: > >> Hi, >> >> This afternoon I just tried a small experiment in the RubyCocoa >> core. You know that every time you send a message from Ruby to >> Objective-C, it goes through #method_missing, which is supposedly >> slow. >> >> I experimented creating the missing method just after >> #method_missing, so that #method_missing would be called only once >> (the other messages would be "direct"). I thought it would be a good >> performance gain. >> >> However, from a quick test, it doesn't seem to be better (it's even >> sometimes worse). >> >> Any idea? I attached the patch and the bench test to this message. >> >> Laurent >> >> < >> define_missing >> .diff><bench.rb>_______________________________________________ >> Rubycocoa-devel mailing list >> Rubyc****@lists***** >> http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel > > _______________________________________________ > Rubycocoa-devel mailing list > Rubyc****@lists***** > http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel