Estoy construyendo un mapa de envío de mensajes en C# y sobre todo jugando con diferentes enfoques. Tengo curiosidad sobre la diferencia de rendimiento que estoy midiendo, pero no es obvio por qué mirando el IL.¿Por qué el lanzamiento a un tipo genérico es más lento que un lanzamiento explícito en C#?
El mapa mensaje:
delegate void MessageHandler(Message message);
AddHandler(Type t, MessageHandler handler)
{
/* add 'handler' to messageMap invocation list */
}
delegate void GenericMessageHandler<T>(T message);
AddHandler<T>(GenericMessageHandler<T> handler) where T: Message
{
AddHandler(typeof(T), e => { handler((T)e); });
}
Dictionary<Type, MessageHandler> messageMap;
entonces tengo una jerarquía de clases de mensajes, similar a EventArgs en WPF, por ejemplo:
public class Message {}
public class VelocityUpdateMessage : Message
y de observación clases con funciones de controlador:
void HandleVelocityUpdate(VelocityUpdateMessage message) { ... }
Estoy midiendo 2 formas de agregar & controladores de invocación. Estoy completando la llamada de delegado para poder obtener un poco de seguridad de tipo conceptual y ahí radica la diferencia de rendimiento.
Enfoque 1: llamadas de los oyentes
AddHandler(typeof(VelocityUpdateMessage),
e => { HandleVelocityUpdate((VelocityUpdateMessage)e); });
Enfoque 2: llamadas de los oyentes
AddHandler<VelocityUpdateMessage>(HandleVelocityUpdate);
Ambos enfoques construir un delegado MessageHandler que hace un reparto y la misma llamada a un método, pero llamar a los delegados construido usando el enfoque n. ° 2 es un poco más lento a pesar de que el IL generado parece idéntico. ¿Es una sobrecarga de tiempo de ejecución adicional en el envío a un tipo genérico? ¿Es la restricción de tipo? Espero que los delegados JITted sean los mismos una vez que se resuelva el tipo genérico.
Gracias por cualquier información.
¿Cómo estás midiendo? Eso es extremadamente importante con estas micro-optimizaciones. –