首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 反射效能測試與優化策略分析

     編輯:關於C#

測試背景

比較三種序列化物件建立方式的效能:
1. 反射建立 (Activator.CreateInstance + PropertyInfo.SetValue)
2. 動態編譯 (CodeDom / Roslyn)
3. 靜態編譯序列化適配器 (預先生成強型別存取委托)

測試結果摘要 (50,000 次迭代)

方式耗時 (秒)相對效能
靜態編譯序列化 (原生)~1.1基準 (1x)
反射序列化~4.2 ~ 7.84-7x 慢
動態編譯序列化~4.1 ~ 7.54-7x 慢
動態建立適配器 (強型別委托)~1.1接近原生 (1x)

關鍵發現

  1. 反射本身非主要瓶頸:反射序列化與動態編譯耗時相近,證明反射取得屬性資訊佔比不大,主要開銷在 SetValue 晚期繫結呼叫。
  2. 強型別委托逼近原生速度:預先為每個型別生成 Action<T, object> 或 Func<object, T> 委托,直接存取屬性,效能提升 **4-7 倍**,接近手寫程式碼。
  3. IMessageSink (Remoting) 開銷極大:10 萬次迴圈測試,反射 11.2 秒 vs 直接存取 0.015 秒,**差距近 1000 倍**。

優化策略

1. 快取反射資訊

static readonly Dictionary PropertyCache = new();
PropertyInfo[] props = PropertyCache.GetOrAdd(type, t => t.GetProperties());

2. 使用 Delegate.CreateDelegate 生成強型別存取器

var setMethod = prop.GetSetMethod();
var setter = (Action)Delegate.CreateDelegate(
    typeof(Action), setMethod);
// 呼叫:setter(instance, value);

3. Expression Tree 建立 Lambda (可讀性佳)

var instance = Expression.Parameter(typeof(object), "instance");
var value = Expression.Parameter(typeof(object), "value");
var castInstance = Expression.Convert(instance, type);
var castValue = Expression.Convert(value, prop.PropertyType);
var call = Expression.Call(castInstance, prop.GetSetMethod(), castValue);
var lambda = Expression.Lambda>(call, instance, value);
var setter = lambda.Compile();

4. 原始碼產生器 / Source Generator (現代最佳)

編譯期自動生成強型別序列化邏輯,零反射、零啟動開銷,效能最優。

結論

  • 熱路徑**避免直接反射呼叫** PropertyInfo.SetValue。
  • 採用 **Delegate / Expression Tree / Source Generator** 預先編譯存取邏輯。
  • 若使用序列化庫 (Newtonsoft.Json, System.Text.Json, MessagePack),內部已高度優化,優先使用成熟庫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved