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