首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

從組合語言層面證明:泛型不會降低執行效能

     編輯:組合語言

延續前文效能測試,本文採用「核武級」手段——直接對比 非泛型(MyArrayList)與 泛型(MyList<object>)在 JIT 編譯後的 x86 機器碼,從 CPU 指令層面一錘定音:兩者執行路徑幾乎完全相同,不存在效能差距。

實驗設計:消除干擾變因

  • 兩個容器類別結構完全對稱,唯一差異在於內部陣列型別:object[] vs T[]。
  • 索引器 get/set 標記 [MethodImpl(MethodImplOptions.NoInlining)],強制 JIT 產生獨立方法體,避免內聯干擾觀察。
  • Main 方法先觸發 JIT,再於 Console.ReadLine() 暫停,附加 WinDbg 分析。

記憶體佈局驗證:物件結構同構

透過 !do 檢視 Managed Heap 上的物件:

> !do 0205be3c (MyArrayList)
Fields: MT Field Offset Type VT Attr Value Name
5c1b41d0 4000001 4 System.Object[] 0 instance 0205be48 m_items

> !do [MyList<object> 位址]
Fields: ... Offset 4 ... System.Object[] ... m_items

結論:兩者物件佈局完全一致,m_items 均位於物件起始位址 + 4 Bytes,型別皆為 Object[]。泛型實例化為參考型別時,CLR 共享同一套程式碼與結構。

陣列物件內部結構

觀察 System.Object[] 記憶體佈局(dd 位址):

  • Offset 0:MethodTable 指標
  • Offset 4:陣列長度
  • Offset 8:元素型別 MethodTable
  • Offset 12 (0xC):起始元素資料(參考型別存物件指標)

Main 方法機器碼對比:關鍵證據

反組譯 Main 中對兩者索引器 get_Item 的呼叫片段:

; --- MyArrayList.get_Item(Int32) ---
01d4012d mov ecx, esi          ; this 指標
01d4012f xor edx, edx          ; 參數 index = 0
01d40131 call dword ptr ds:[343424h]  ; 呼叫入口點

; --- MyList`1[object].get_Item(Int32) ---
01d40137 mov ecx, edi          ; this 指標
01d40139 xor edx, edx          ; 參數 index = 0
01d4013b call dword ptr ds:[343594h]  ; 呼叫入口點

指令序列完全同構:參數傳遣(ECX=this, EDX=index)、呼叫慣例、間接呼叫機制無任何差異。唯一不同僅是入口點表位址(對應各自的 MethodDesc)。

總結

從物件佈局、陣列結構、呼叫端機器碼三個維度鐵證如山:泛型在參考型別實例化時,CLR 採用程式碼共享策略,執行效能與手寫 object 版本無異。 任何「泛型較慢」的論調,在 x86 指令面前都不攻自破。

作者提醒:除非必要,勿沉迷 IL/Asm 分析。高階語言、架構設計、演算法才是解決實際問題的主戰場。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved