Sto costruendo una mappa di invio messaggi in C# e principalmente sto solo giocando con approcci diversi. Sono curioso di una differenza di prestazioni che sto misurando, ma non è ovvio perché osservando l'IL.Perché il cast di un tipo generico è più lento di un cast esplicito in C#?
La mappa messaggio:
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;
Ho poi hanno una gerarchia di classi di messaggi, simili a EventArgs in WPF, ad esempio:
public class Message {}
public class VelocityUpdateMessage : Message
e osservatori classi con funzioni di gestione:
void HandleVelocityUpdate(VelocityUpdateMessage message) { ... }
Sto misurando 2 modi di aggiungere i gestori invocando &. Sto avvolgendo la chiamata del delegato in modo da ottenere un po 'di sicurezza concettuale e qui sta la differenza perfetta.
Approccio 1: ascoltatore chiama
AddHandler(typeof(VelocityUpdateMessage),
e => { HandleVelocityUpdate((VelocityUpdateMessage)e); });
Approccio 2: ascoltatore chiama
AddHandler<VelocityUpdateMessage>(HandleVelocityUpdate);
Entrambi gli approcci costruire un delegato messageHandler che fa un cast e lo stesso metodo di chiamata, ma chiamando i delegati costruita utilizzando l'approccio # 2 è un po 'più lento anche se l'IL generato sembra identico. È un overhead di runtime aggiuntivo nel cast di un tipo generico? È il vincolo del tipo? Mi aspetto che i delegati JITted siano gli stessi una volta risolto il tipo generico.
Grazie per qualsiasi informazione.
Come stai misurando? Questo è estremamente importante con queste micro-ottimizzazioni. –