Background: my game is using a component system. I have an Entity class which has a list of IComponent instances in a List<IComponent>. My current implementation of Entity.GetComponent<T>() is:
return (T)this.components.Single(c => c is T);
After adding collision detection, I noticed my game dropped to 1FPS. Profiling revealed the culprit to be this very call (which is called 3000+ times per frame).
3000x aside, I noticed that calling this 300k times takes about 2 seconds. I optimized it to a simple iterative loop:
foreach (IComponent c in this.components) {
if (c is T) {
return (T)c;
}
}
return default(T);
This code now runs in about 0.4s, which is an order of magnitude better.
I thought Single would be much more efficient than a single foreach loop. What’s going on here?
The doc for
Singlesays:On the other hand
First:So, with
Singleyou traverse the whole sequence withoutshort circuiting, which is what theforeachloop above does. So, useFirstorFirstOrDefaultinstead ofSingle.