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

動態編譯效能進階:拋棄反射,用介面 + 實例方法實現零反射高速調用

     編輯:關於C#

動態編譯雖強,若每次調用仍靠 MethodInfo.Invoke 反射,效能優勢盡失。本文揭示關鍵技巧:**將靜態方法改為實例方法、實作共用介面、編譯後轉型為介面實例、快取介面直接調用**,實測 100 萬次循環下 **快 10 倍以上**(330ms → 24ms),甚至超越 Newtonsoft.Json。

為什麼靜態方法只能反射調用?

動態編譯的類別名稱是運行時產生的(如 _336090f4e7724d2585b07e79210decb4),編譯期無法寫死 ClassName.Method(),只能透過反射 Invoke。

三步改造:從靜態到介面實例

1. 定義共用介面

namespace blqw {
    public interface IGetString {
        string GetString(object obj);
    }
}

2. 動態生成的類別實作介面、方法去 static、參數改 object

// 改造前(靜態)
public class _xxx {
    public static string A(User obj) { /* ... */ }
}

// 改造後(實例 + 介面)
public class _xxx : blqw.IGetString {
    public string GetString(object o) {
        User obj = (User)o;
        /* ... 建構 JSON 字串 ... */
    }
}

3. 編譯後轉介面、快取、直接調用

// 編譯
var ass = DynamicCompile_1.CompileAssembly(code, ...);
// 實例化並轉介面(僅第一次需反射)
var getter = (IGetString)ass.GetTypes()[0]
    .GetConstructor(Type.EmptyTypes)
    .Invoke(null);
// 快取 getter
MethodCache[type] = getter;

// 後續調用:零反射
return getter.GetString(user); // 純虛擬呼叫,極快

效能實測:100 萬次循環


// 反射調用靜態方法
var met = typeof(Program).GetMethod("A");
for (int i=0; i<1_000_000; i++) met.Invoke(null, new[] { user });
// 330ms 級

// 介面實例調用
var getter = (IGetString)Activator.CreateInstance(typeof(Program));
for (int i=0; i<1_000_000; i++) getter.GetString(user);
// 24ms 級

結果:

333ms | 25ms
330ms | 24ms
326ms | 24ms
... (10次皆穩定 10倍以上差距)

JSON 序列化實戰對比

純反射       10000次 x10: 168 | 153 | 152 | 152 | 154 | 157 | 157 | 158 | 158 | 153 ms
動態編譯+介面 10000次 x10: 222 | 116 | 118 | 117 | 113 | 109 | 105 | 106 | 105 | 107 ms
Newtonsoft.Json 10000次 x10: 359 | 177 | 192 | 182 | 188 | 189 | 189 | 189 | 187 | 189 ms

動態編譯 + 介面快取 **穩定擊敗 Newtonsoft.Json**,且輸出格式完全一致。

效能測試截圖

關鍵總結

  • 介面是橋樑:編譯期知介面,運行期得實例,雙贏。
  • 快取是核心:Dictionary<Type, IGetString> 確保每型別只編譯/實例化一次。
  • 參數用 object:介面方法簽名固定為 GetString(object),內部再 cast 回具體型別。
  • 適用場景:高頻序列化、規則引擎、公式計算、映射器——任何「型別固定、邏輯固定、調用極頻」的熱路徑。

下一篇將把這套機制封裝進 DynamicCompile 庫,並展示如何自動為任意型別生成 IGetString 實作代碼,實現真正的「一鍵加速」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved