[.net] Perf considerations: Optional component methods

Started by
15 comments, last by Telastyn 13 years, 8 months ago
Assume the situation of a component-based gameobject system where you derive all your components from a general "Component" class. There are a lot of situation-specific update calls and not every component needs all of them. In fact, most components only utilize few of them.

Let's say we've got this set of methods that could, possibly, be overridden by derived components:
--> OnUpdate
--> OnPreUpdate
--> OnPostUpdate
--> OnRender
--> OnInit
--> OnFirstUpdate
--> OnActivate
--> OnDeactivate

--> OnCollisionBegin
--> OnCollisionEnd
--> OnCollision

--> OnMouseEnter
--> OnMouseLeave
--> OnMouseOver

--> etc. etc.

While there are general methods like OnUpdate that any component will override, more specifiv ones like OnCollision, OnPreUpdate, etc. won't be used much.

Now, to the point: With all those virtual per-frame calls, it looks like a "huge" performance loss, compared to the gain (zero, mostly). Would it be significantly faster to keep a set of delegates, manually created via reflection and null-checking them before calling any of the methods? This would avoid unneccessary calls but include an initialization overhead for each object because each object will need to generate its own delegates.

Another alternative: Using virtual overridden methods (No delegate creation overhead) but a reflection-generated bitmask which of them are actually used. To me, this sounds like the best method. What do ypou think?
Advertisement
Quote:What do ypou think?

First of all I think that a class with an interface containing that many totally unrelated method is clearly violating both the Single Responsibility Principle (SRP) and the Interface Segregation Principle (ISP). You could split this interface into multiple interfaces like IUpdateable, IRenderable, IMouseListener etc. A component then only implements the interfaces it needs. Instead of having one large list of components you let the component register themselves at separate lists: one for IRenderables, one for IUpdateables etc.This will at least fix the ISP problem and the problem that most components do not require all methods (which in fact is strongly related to the ISP problem).
As for the SRP problem: instead of having the component implement all interfaces you could split the functionality into separate classes, one that handles the rendering logic, one that deals with state updates etc. This should simplify your classes and improve the design.

Regarding the performance "issue": virtual calls are not prohibitively expensive in general. So before you try to optimize those calls away: MEASURE!

Regards,
Andre
Andre Loker | Personal blog on .NET
I'm aware of the "design problem" you mentioned but might still prefer it over a lot of separate interfaces due to gameobject overhead issues. There will be a LOT of gameobjects. Each of them keeping *one* list of components is okay, but imagine thousands of projectiles flying around with each of them having five or ten separate interface lists in addition to their general component list!
Of course I don't know about your overall design. What's a component, what's a "game object"? Which components would a single projectile use?

I'm under the impression that you are trying to create "the ultimate flexible design", which will probably collapse under its own weight.

My suggestion: don't overdesign! Keep it simple, make it work first, refactor later. And of course measure/profile to find spots that need attention.
Andre Loker | Personal blog on .NET
It's actually more of a thought experiment right now, nothing really implemented yet. I'm just thinking about how I would start when it finally comes to beginning the project.

Basically I'm thinkinf of a default component based gameobject system. If you're designing a game engine with a lot of different kinds of objects, there are basically two ways of implementing that. An object class hierarchy like that:

Object
--> Movable
-->--> Person
-->--> Tank
-->--> Projectile
--> Static
-->--> Building
-->--> Plant

(etc.)

This design will lead to a lot of copying and pasting as soon as there are types of objects you haven't initially thought of. I've experienced it myself a lot of times, it just sucks in a lot of situations that require a flexible code design. At least, if you want to maintain some level of clean code and keep your copy'paste ration low.

And then, there's this other system, the component based gameobject system. In that, you've just one class, the GameObject. That class does general engine maintenance stuff (which isn't much to do) and represents an object. Each GameObject is assigned any number of components where a Component is a base class that can't exist on its on. A GameObject / Component construct will be a classic composition.

That way, you can easily dynamically add or remove functionality or traits from gameobjects and are completely free as a content integrator or gamedesigner to "compose" any object you like. Typical components are:

Renderer,
Collider,
Camera,
SoundSource,
Transform,
etc.

A projectile now would consist of parameterized components like Transform, Collider, some Renderer and most likely a additional specialized component to deal damage when recieving a collision signal from the Collider component. The nice thing about thi is that you could just add a SoundSource-Component if you'd like it to make a flight sound. Or a Light-Component. Etc. Etc.


Now, the main thing about this system regarding performance is: Keep the overhead low. A GameObject should ideally take a zero-overhead (never achieved) as it doesn't do anything "visible". Furthermore, the number of components per gameobject should affect performance least possible. With a gameobject keeping a lot of lists, one for each component interface type, I imagine the overhead being "big". Didn't test it, though.
Component based design is awkward at best in .NET. Doing it via inheritance rather than some message passing paradigm is (I would consider) not viable.
Quote:Original post by Telastyn
Component based design is awkward at best in .NET. Doing it via inheritance rather than some message passing paradigm is (I would consider) not viable.


Please explain yourself a little further.
OP, you might find find this thread, this thread, and this thread useful, even if they're about C++ rather than C#.
Quote:Original post by Fetze
Quote:Original post by Telastyn
Component based design is awkward at best in .NET. Doing it via inheritance rather than some message passing paradigm is (I would consider) not viable.


Please explain yourself a little further.


Sure. What do you find unclear, or what are you looking for elaboration on?
More or less your whole comment ;-)

--> Explain, why you consider doing a component-based gameobject system in .Net is awkward / not a good idea
--> Explain, why doing it over inheritance is especially not viable

I can only guess what gives you the impression for both points? Also, I'd like to hear your "message passing paradigm" alternative for inheritance. Are you talking about some kind of gameobject-local message queue?

This topic is closed to new replies.

Advertisement