四探C#類與結構體究竟誰快——跨程序集(assembly)調用

前面的三次測試都是在同一個項目內的,既處於同一個程序集。那麼,跨程序集調用會怎麼樣呢?

因爲爲了保證可維護性,我們會把一些常用操作封裝到類庫中去。然後實際項目開發時,引用該類庫,使得解決方案中存在多個項目。編譯完成後,將會是一個主要的exe和若干個dll文件,主exe程序集中的代碼會調用dll程序集,既形成了跨程序集調用。

分析跨程序集調用的性能,有助優化類庫架構的設計。


一、測試辦法

其實步驟很簡單——
1.重新打開VS2005。或關閉解決方案。
2.新建一個“Windows應用程序”項目。如“TryPointerCallns2005”。
3.添加項目,選擇上次的“TryPointerCall2005”。現在解決方案中就有兩個項目了。
4.選擇第2步時新建的項目(TryPointerCallns2005),添加引用,將“TryPointerCall2005”加上去。
5.調整項目屬性,允許不安全的代碼。
6.新建一個類(TestCall),將測試代碼全部Copy過來(注意只複製測試代碼,不復制IPointerCall、PointerCall等實現)。
7.修改窗口界面,調用TestCall的測試代碼。


二、測試環境

  編譯器——
VS2005:Visual Studio 2005 SP1。
採用上述編譯器編譯爲Release版程序,最大速度優化。

  機器——
HP CQ42-153TX
處理器:Intel Core i5-430M(2.26GHz, Turbo 2.53GHz, 3MB L3)
內存容量:2GB (DDR3-1066)


三、測試結果

  測試結果如下——
== PointerCallTool.TryIt() ==
硬編碼.棧變量: 162
硬編碼.棧分配: 168
硬編碼.靜態: 164
靜態調用: 160
64硬編碼.棧變量: 161
64硬編碼.棧分配: 160
64硬編碼.靜態: 160
64靜態調用: 162
調用派生類: 1118
調用密封類: 1049
調用結構體: 1069
調用基類: 1128
調用派生類的接口: 1132
調用密封類的接口: 1135
調用結構體的接口: 1453
基類泛型調用派生類: 1769
基類泛型調用基類: 1774
接口泛型調用派生類: 2230
接口泛型調用密封類: 2240
接口泛型調用結構體: 1215
接口泛型調用結構體引用: 1127
接口泛型調用基類: 2241
接口泛型調用派生類的接口: 2230
接口泛型調用密封類的接口: 2244
接口泛型調用結構體的接口: 2302


  可見,在跨程序集調用時,調用密封類、調用結構體不會被即時編譯器(JIT)做內聯優化,而被當做普通的虛方法調用。

  所以,對於那些要求性能的代碼,應儘量保證在同一程序集內,避免將其放在類庫工程,這樣能儘可能地利用即時編譯器(JIT)內聯優化的機會。

(完)

源代碼下載——
http://files.cnblogs.com/zyl910/TryPointerCall_4.rar

目錄——
C#類與結構體究竟誰快——各種函數調用模式速度評測:http://blog.csdn.net/zyl910/article/details/6788417
再探C#類與結構體究竟誰快——考慮棧變量、棧分配、64位整數、密封類:http://blog.csdn.net/zyl910/article/details/6793908
三探C#類與結構體究竟誰快——MSIL(微軟中間語言)解讀:http://blog.csdn.net/zyl910/article/details/6817158
四探C#類與結構體究竟誰快——跨程序集(assembly)調用:http://blog.csdn.net/zyl910/article/details/6839868

發佈了68 篇原創文章 · 獲贊 43 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章