2012-01-21 21 views
6

我正在用C#構建一個消息發佈圖,並且大多隻是圍繞一些不同的方法進行遊戲。我對我正在測量的性能差異感到好奇,但是爲什麼從IL看起來並不明顯。爲什麼在C#中投射到一個通用類型比顯式投射要慢?

消息映射:

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; 

我然後有消息,類似於WPF的EventArgs的一個類層次結構,例如:

public class Message {} 
public class VelocityUpdateMessage : Message 

和觀察者類與處理函數:

void HandleVelocityUpdate(VelocityUpdateMessage message) { ... } 

我正在測量添加&調用處理程序的兩種方法。我正在封裝委託調用,以便我可以獲得一些概念類型的安全性,其中存在性能差異。

方法1:監聽電話

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

方法2:偵聽器調用

AddHandler<VelocityUpdateMessage>(HandleVelocityUpdate); 

兩種方法都建立了MessageHandler委託,使一個演員和相同的方法調用,但調用代表內置使用即使生成的IL看起來相同,方法#2稍慢一點。在轉換爲泛型類型時額外的運行時開銷是多少?它是類型約束嗎?我希望一旦泛型類型得到解決,JITted委託就是相同的。

感謝您的任何信息。

+2

你是怎麼測量的?這對於這些微觀優化非常重要。 –

回答

0

好吧,我不得不看MethodBody.GetILAsByteArray()IL而非ILSpy結果代表去的這條底線。使用一個通用的委託來包裝我的消息處理程序和鑄鐵消息類型生成:

0000 : ldarg.0 
0001 : ldfld 
0006 : ldarg.1 
0007 : unbox.any 
000C : callvirt void MessageTest.Message+tMessageHandler`1[MessageTest.VelocityUpdateMessage].Invoke(‌​MessageTest.VelocityUpdateMessage) 
0011 : ret 

其中具有明確的投包裝委託生成:

0000 : ldarg.0 
0001 : ldarg.1 
0002 : castclass 
0007 : call void Message.Component.HandleVelocityUpdate(MessageTest.VelocityUpdateMessage) 
000C : ret 

所以,是的,沒有從使用泛型最小的開銷通過這種方式。

3

下面的代碼行在每次調用時都會創建一個匿名類型的新實例。這可能是你的表現差異的原因嗎?

AddHandler(typeof(T), e => { handler((T)e); }); 
+0

該行不包含「new {...}」。匿名類型在哪裏? – dtb

+0

爲了澄清,我在調用委託(調度消息到處理程序)時看到了性能差異,我沒有分析AddHandler調用,因爲它們是設置代碼。正如克里斯托弗所說,我將爲每種類型獲得一種新的方法,但我的測試代碼只是在一個緊密的循環中反覆調用相同的處理程序,因此代碼生成的命中應該只是一個小小的點。也許它比我想象的要多。我看到#1的10萬次通話耗時約70毫秒,#2耗費約110毫秒。這不像調用Delegate.DynamicInvoke那麼重要。 –

+0

它不是一個匿名類型,至少不是一個正式的C#語言定義。有一個使lambda表達式工作的隱藏類,* new *表達式也是隱藏的。 OP做出了相反的觀察。 –