XNA / C #: Object Objects and Type (T) Performance

In our game (mobile-oriented), we have several different types of entities, and I write factory / repository to process instances of new objects. Each particular type of object has its own factory implementation, and these plants are managed by EntityRepository.

I would like to implement a repository as such:

Repository { private Dictionary <System.Type, IEntityFactory<IEntity>> factoryDict; public T CreateEntity<T> (params) where T : IEntity { return factoryDict[typeof(T)].CreateEntity() as T; } } 

Usage example

 var enemy = repo.CreateEntity<Enemy>(); 

but I'm worried about performance, especially related to the typeof (T) operation in the above. I understand that the compiler will not be able to determine the type of T, and it will need to be determined at run time through reflection, is this correct? One of the options:

 Repository { private Dictionary <System.Type, IEntityFactory> factoryDict; public IEntity CreateEntity (System.Type type, params) { return factoryDict[type].CreateEntity(); } } 

to be used as

 var enemy = (Enemy)repo.CreateEntity(typeof(Enemy), params); 

in this case, when typeof () is called, the type is at hand and can be determined by the compiler (right?), and performance should be better. Will there be a noticeable difference? any other considerations? I know that I can also have a method like CreateEnemy in the repository (we have only a few types of entities) that would be faster, but I would prefer to keep the repository as small as possible than the entity.

EDIT:

I know that this is most likely not to be a bottleneck, my only concern is that it is such a waste of time to use time for reflection when there is a slightly less dry alternative. And I think this is an interesting question :)

I did some benchmarking that turned out to be quite interesting (and which seem to confirm my initial suspicions).

Using the performance measurement tool that I found at http://blogs.msdn.com/b/vancem/archive/2006/09/21/765648.aspx (which runs the test method several times and displays metrics like average time and etc.). I did a basic test, testing:

 private static T GenFunc<T>() where T : class { return dict[typeof(T)] as T; } 

vs

  private static Object ParamFunc(System.Type type) { var d = dict[type]; return d; } 

called

 str = GenFunc<string>(); 

vs

 str = (String)ParamFunc(typeof(String)); 

respectively. Paramfunc shows a remarkable performance improvement (GenFunc takes an average of 60-70% of the time), but the test is quite rudimentary, and I can skip a few things. In particular, how casting is performed in a common function.

The interesting thing is that there is a small (negligible) performance obtained by "caching" a type in a variable and passing it to ParamFunc vs using typeof () every time.

+4
source share
2 answers

Generics in C # do not use or do not need to be reflected.

Internal types are passed as RuntimeTypeHandle values. And the typeof statement is mapped to Type.GetTypeFromHandle ( MSDN ). Despite Rotor or Mono, I would expect GetTypeFromHandle be O (1) and very fast (for example: array search).

So, in the general case ( <T> ), you essentially pass RuntimeTypeHandle to your method and call GetTypeFromHandle in your method. In your custom case, you first call GetTypeFromHandle , and then pass the resulting Type to your method. Performance should be almost the same and massively outweighed by other factors, for example, in any places where you allocate memory (for example: if you use the params ).

But this is still a factory. Of course, this will not be called more than a couple of times per second? Is it even worth optimizing?

+6
source

You always hear slow reflection, but in C #, there is actually a quick reflection and a slow reflection. typeof - quick reflection - basically it's the overhead of invoking a method that is almost infinitely small.

I would promise a lunch of steak and lobster that this will not be a performance bottleneck in your application, so you should not even spend (or ours) time optimizing it. It has been said a million times earlier, but it is worth saying again: "Premature optimization is the root of all evil."

So, finish writing the application and then the profile to determine where your bottlenecks are. If this turns out to be one of them, then and only then spend time optimizing it. And let me know where you would like to dine.


In addition, my comment above should be repeated, so you do not spend more time inventing the wheel: any decent IoC container (for example, AutoFac) can automatically create factory methods. If you use one of them, you do not need to write your own repository or write your own CreateEntity() methods or even call the CreateEntity() method yourself - the library does all this for you.

+1
source

All Articles