国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

淺談.NET反射機制的性能優(yōu)化 附實例下載

2024-07-10 13:24:06
字體:
來源:轉載
供稿:網友
可能大家談到反射面部肌肉都開始抽搐了吧!因為在托管語言里面,最臭名昭著的就是反射!它的性能實在是太低了,甚至在很多時候讓我們無法忍受。不過不用那么糾結了,老陳今天就來分享一下如何來優(yōu)化反射!

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

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

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

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

復制代碼 代碼如下:


namespace ReflectionOptimization
{
public sealed class TestObject
{
public int Add(int a, int b)
{
// 簡單演示
return a + b;
}
}
}


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

復制代碼 代碼如下:


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));

// 返回執(zhí)行時間
return stopwatch.Elapsed.TotalMilliseconds;
}


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

編碼實現(xiàn)
首先我們來看看原生反射的實現(xiàn):

復制代碼 代碼如下:


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動態(tài)編程的實現(xiàn):

復制代碼 代碼如下:


dynamic obj = new TestObject();

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


最后我們看看如何使用委托來優(yōu)化反射:

復制代碼 代碼如下:


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

// 實現(xiàn)
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);


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

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

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

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

Debug模式:

調用方式第一次第二次第三次第四次第五次

Generic Call1.0224251.0128850.9907751.0209501.046880

Reflection147.489220146.012010142.690080139.189335141.663475

dynamic9.6458509.9799659.3072359.5326659.730030

Func1.2018601.2148001.1702151.1892801.239485

Delegate1.0622151.0616351.0675101.0471801.075190

Release模式:

調用方式第一次第二次第三次第四次第五次

Generic Call0.7456000.7413650.7221450.7326300.725645

Reflection141.778260142.855410142.346095139.649990138.541285

dynamic9.63146010.3418509.2842309.4575809.060470

Func0.8821000.8526800.8756950.8546550.831670

Delegate0.7102800.7224650.7233550.7271750.693320

點評&結論:

  • 使用委托優(yōu)化反射之后,其性能與直接調用相差無幾,保持在同一個數(shù)量級之內,對性能要求極度苛刻時推薦此方案;
  • 顯式委托(Delegate)和匿名委托(Func)性能差異非常不明顯,但顯式委托的性能還是好一點; 
  • 原生委托比直接調用慢出了兩個數(shù)量級,性能差異達到了200倍之多!
  • .NET 4的動態(tài)編程語法相當簡潔,其性能只比直接調用高出一個數(shù)量級,由于其語法相當簡潔,我們推薦這種做法!
  • 原生反射技術在Debug模式和Release模式下沒有太大差異,但其他方式有較為明顯的優(yōu)化效果(請思考為什么);
  • 雖然我們今天的測試不能完全意味著反射優(yōu)化之后可以和直接調用相媲美,但至少可以從某種程度上擊敗那些個謠言——誰說反射就一定會慢(嘻嘻)!

  • 代碼下載:淺談反射優(yōu)化
    發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發(fā)表
    主站蜘蛛池模板: 桦南县| 洪雅县| 射阳县| 绥化市| 丽水市| 洮南市| 龙门县| 太仓市| 吴忠市| 尚义县| 涟源市| 大化| 榆林市| 新绛县| 华安县| 宜黄县| 北川| 华容县| 开封县| 常山县| 乌拉特中旗| 土默特右旗| 桐梓县| 沂水县| 遂昌县| 沈丘县| 昭觉县| 綦江县| 沙雅县| 乌鲁木齐市| 昌江| 门头沟区| 宜丰县| 汶川县| 上高县| 万全县| 秦皇岛市| 神木县| 神木县| 湾仔区| 南靖县|