Почему приведение к универсальному типу выполняется медленнее, чем явное приведение в C #?

Я создаю карту отправки сообщений на C # и в основном просто экспериментирую с разными подходами. Мне любопытно узнать о разнице в производительности, которую я измеряю, но не совсем понятно, почему, глядя на IL.

Карта сообщений:

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;

Затем у меня есть иерархия классов сообщений, аналогичная EventArgs в WPF, например:

public class Message {}
public class VelocityUpdateMessage : Message

и классы наблюдателей с функциями обработчика:

void HandleVelocityUpdate(VelocityUpdateMessage message) { ... }

Я измеряю 2 способа добавления и вызова обработчики.Я оборачиваю вызов делегата, чтобы получить некоторую концептуальную безопасность типов, и в этом заключается разница в производительности.

Подход 1: вызовы слушателя

AddHandler(typeof(VelocityUpdateMessage), 
           e => { HandleVelocityUpdate((VelocityUpdateMessage)e); });

Подход 2: вызовы слушателя

AddHandler<VelocityUpdateMessage>(HandleVelocityUpdate);

Оба подхода создают делегат MessageHandler, который выполняет приведение и тот же вызов метода, но вызов делегатов, созданных с использованием подхода № 2, выполняется немного медленнее даже хотя сгенерированный IL выглядит идентично. Это дополнительные накладные расходы времени выполнения при приведении к универсальному типу? Это ограничение типа? Я ожидаю, что делегаты JITted будут такими же, как только будет разрешен общий тип.

Спасибо за любую информацию.

6
задан Jonathan Allen 21 January 2012 в 08:59
поделиться