From: Jonathan P. <jp...@dc...> - 2006-02-22 20:41:27
|
On 22 Feb 2006, at 18:16, Tim Burks wrote: > One possible optimization is to replace the Sprite class with a > version written in Objective-C. Ideally, we could just swap in a > new parent class with no changes to its subclasses. But in > practice, I had several problems: > > * The Ruby versions of Sprite and its subclasses must already be > using Objective-C alloc/init construction instead of new. > > * Methods in Ruby subclasses that will be replaced by Objective-C > classes must map to Objective-C message names. This is true - but in RubyCocoa you never need the trailing underscore in method names. You do need it, however, when calling ns_overrides. > * Something needs to be done to resolve the different calling > conventions used by Ruby attribute setters ("object =") and Cocoa > KVC setters ("setObject"). Have you any ideas for how best to resolve this? > * When a Ruby subclass overrides an Objective-C class method, an > "ns_overrides" declaration seems to be necessary. But if the > parent class is switched back to Ruby (for debugging or testing), > that "ns_overrides" is a fatal error. Good point. I'm hoping it might be possible to do away with ns_overrides altogether... > Surprisingly, I found that replacing the Ruby Sprite class with an > Objective-C version didn't speed up my game; in fact it seemed to > slow it down a bit. The reason for this was that the new version > was making more calls across the bridge, and calls across the > bridge are much more expensive than code implemented in Ruby or > calls to standard Ruby C extensions. I made some crude > measurements and estimated that the best I could hope for was a few > thousand bridge crossings per second. That's plenty for a typical > Cocoa app, but not enough for an arcade game that uses RubyCocoa to > draw and manage objects. So I switched back to my Ruby Sprite > class and rewrote my object drawing functions as standard Ruby C > extensions. After that I had only 2-3 bridge crossings per frame > and the game was snappy again, even with the brute-force Ruby > collision detection that I had worried about initially. I think the drawing is probably one of the slowest things. Have you tried getting a profile using Shark? I looked briefly and noticed that NSWindow clears the window as well as the draw method in Game. Together these took up about 20% of CPU time. Turning off anti- aliasing would speed things up too. Or using OpenGL! :) I would hope that using plain ruby Sprite objects and trying to keep as much as possible in Ruby-land (e.g., only calling ObjC for the drawing) should give reasonable performance. I agree that bridge crossings are expensive. Cheers, Jonathan |