一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 淺談.NET反射機制的性能優化 附實例下載

淺談.NET反射機制的性能優化 附實例下載

2019-09-29 11:47asp.net教程網 ASP.NET教程

在進入解釋型模版引擎的探討之前,我決定先分享一下這篇博客。因為在解釋型引擎里將會引入反射的概念來實現更多、更復雜的功能

可能大家談到反射面部肌肉都開始抽搐了吧!因為在托管語言里面,最臭名昭著的就是反射!它的性能實在是太低了,甚至在很多時候讓我們無法忍受。不過不用那么糾結了,老陳今天就來分享一下如何來優化反射! 

概述 
本文涉及到的反射優化的途徑有如下兩種: 

通過Delegate.CreateDelegate()創建委托進行優化 
通過.NET4的動態運行時進行優化 
如果您還知道其他更加有效的優化途徑,請不吝賜教! 

準備工作 
今天我們總計要對比五種不同的調用對象成員的方式,也算是一種性能測評。 

在開始之前,我們首先定義一個簡單的對象和一個方法,以供測試之用: 

復制代碼代碼如下:


namespace ReflectionOptimization 

public sealed class TestObject 

public int Add(int a, int b) 

// 簡單演示 
return a + b; 



這個類非常簡單,只提供了一個方法,這個方法返回兩個整形的和。接下來我們看看執行時間測量的代碼,很簡單,想必您已經駕輕就熟了: 

復制代碼代碼如下:


private static double _Run(string description, Action<int, int> action, int a, int b) 

if (action == null) throw new ArgumentNullException("action"); 

// 啟動計時器 
var stopwatch = Stopwatch.StartNew(); 

// 運行要測量的代碼 
action(a, b); 

// 終止計時 
stopwatch.Stop(); 

// 輸出結果 
Console.WriteLine("{0}: {1}", description, stopwatch.Elapsed.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); 

// 返回執行時間 
return stopwatch.Elapsed.TotalMilliseconds; 


以上測量時間的方法返回了執行時間,因為我們要在后面用到這個值,在執行多次之后取個平均值,以求測試的公平性、權威性。 

編碼實現 
首先我們來看看原生反射的實現: 

復制代碼代碼如下:


var obj = new TestObject(); 
var add = obj.GetType().GetMethod("Add"); 

for (var i = 0; i < _TIMES; i++) add.Invoke(obj, new object[] {a, b}); 


然后我們看看.NET4動態編程的實現: 

復制代碼代碼如下:


dynamic obj = new TestObject(); 

// 有木有發現這個代碼超級簡單? 
for (var i = 0; i < _TIMES; i++) obj.Add(a, b); 


最后我們看看如何使用委托來優化反射: 

復制代碼代碼如下:


// 委托 
public delegate int AddMethod(int a, int b); 

// 實現 
var obj = new TestObject(); 
var objType = obj.GetType(); 
var add = objType.GetMethod("Add"); 
var d = (AddMethod)Delegate.CreateDelegate(typeof(AddMethod), obj, add); 

for (var i = 0; i < _TIMES; i++) d(a, b); 


上面的代碼看起來多了幾行,而且還需要自定義一個委托,寫起來挺麻煩的。因此我們的測試代碼里面還實現了另外一種形式,其實它也是委托: 

var d = (Func<TestObject, int, int, int>)Delegate.CreateDelegate(typeof(Func<TestObject, int, int, int>), add); 

測試總結 
我們首先在Debug模式下將整個測試代碼運行5遍,然后分別記錄平均值,然后再到Release模式下重復該測試。 

測試的過程不再闡述,測試結果整理如下: 

Debug模式:

調用方式

第一次

第二次

第三次

第四次

第五次

Generic Call

1.022425

1.012885

0.990775

1.020950

1.046880

Reflection

147.489220

146.012010

142.690080

139.189335

141.663475

dynamic

9.645850

9.979965

9.307235

9.532665

9.730030

Func

1.201860

1.214800

1.170215

1.189280

1.239485

Delegate

1.062215

1.061635

1.067510

1.047180

1.075190

Release模式:

調用方式

第一次

第二次

第三次

第四次

第五次

Generic Call

0.745600

0.741365

0.722145

0.732630

0.725645

Reflection

141.778260

142.855410

142.346095

139.649990

138.541285

dynamic

9.631460

10.341850

9.284230

9.457580

9.060470

Func

0.882100

0.852680

0.875695

0.854655

0.831670

Delegate

0.710280

0.722465

0.723355

0.727175

0.693320

點評&結論:

  • 使用委托優化反射之后,其性能與直接調用相差無幾,保持在同一個數量級之內,對性能要求極度苛刻時推薦此方案;

  • 顯式委托(Delegate)和匿名委托(Func)性能差異非常不明顯,但顯式委托的性能還是好一點; 

  • 原生委托比直接調用慢出了兩個數量級,性能差異達到了200倍之多!

  • .NET 4的動態編程語法相當簡潔,其性能只比直接調用高出一個數量級,由于其語法相當簡潔,我們推薦這種做法!

  • 原生反射技術在Debug模式和Release模式下沒有太大差異,但其他方式有較為明顯的優化效果(請思考為什么);

  • 雖然我們今天的測試不能完全意味著反射優化之后可以和直接調用相媲美,但至少可以從某種程度上擊敗那些個謠言——誰說反射就一定會慢(嘻嘻)!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎影视在线影院在线观看观看 | 成品人视频w免费观看w | 99久久中文字幕伊人 | 青青青在线视频 | 亚洲免费小视频 | 果冻传媒和91制片厂网站软件 | 国内会所按摩推拿国产 | japonensis中国东北老人 | 欧美日韩在线观看区一二 | 国产精品日本一区二区不卡视频 | 精品无码乱码AV | 国产欧美视频高清va在线观看 | 日本老妇人乱视频 | 亭亭色| 免费黄色小说 | 亚洲乱码一区二区三区国产精品 | 91制片厂制作果冻传媒八夷 | xxxx意大利xxxxhd | 精品久久久久久久高清 | 亚洲国产成人久久精品影视 | 北岛玲亚洲一区在线观看 | 国产日本久久久久久久久婷婷 | 国产精品1页| 五月激激激综合网色播免费 | 调教催眠改造np总攻 | 亚洲国产成人精品激情 | 99久久国产综合精品1尤物 | 4438全国免费观看 | 欧美第一视频 | 精品一区二区三区免费观看 | 成人久久伊人精品伊人 | 513热点网深夜影院影院诶 | 国产精品色爱综合网 | 506rr亚洲欧美 | 法国老妇性xx在线播放 | hd最新国产人妖ts视频 | 99热热99| 免费观看在线观看 | 91看片淫黄大片.在线天堂 | 丁香六月色婷婷综合网 | 99热久热这里只精品 |