Dot-Net

為什麼 PropertyInfo SetValue 和 GetValue 這麼慢?

  • October 7, 2012

為什麼PropertyInfo獲取和設置屬性的方法這麼慢?如果我使用 建構委託Reflection.Emit,它會快得多。

他們是否在做一些重要的事情,以便他們花費的時間是合理的?那就是……我是否通過使用Reflection.Emit建構委託而不是使用 PropertyInfo 的GetValueSetValue(除了開發速度)而遺漏了一些東西?

PS:請舉證,不要只憑猜測!

的實現RuntimePropertyInfo(它是PropertyInfo執行時類型的具體子類)實現GetValueSetValue通過反射(MethodInfo.Invoke)呼叫 getter 和 setter 方法,而您生成的委託可能直接呼叫這些方法。因此,問題歸結為:RuntimeMethodInfo.Invoke與編譯呼叫相比,為什麼這麼慢?

當你反編譯(或查看參考源)RuntimeMethodInfo.Invoke時,你可以看到這可能是因為Invoke執行了很多任務:

  • 它執行一致性檢查(傳遞的參數的數量和類型是否與簽名匹配?傳遞的實例是否與聲明類型匹配?儘管方法是靜態的,但是否傳遞了實例?),
  • 它執行可見性和(如果繞過可見性檢查)安全檢查,
  • 它解開參數數組,以特殊方式處理 ref 參數,以便以後可以將它們寫回,
  • 如有必要,它會拆箱參數,
  • 它需要根據執行時類型句柄和與RuntimeMethodHandle關聯的方法句柄找到方法指針,然後呼叫該方法,
  • 如有必要,它將返回值裝箱,並且
  • 它將任何 ref/out 參數裝箱並放入參數數組中。

執行時將您的委託編譯為可執行的本機程式碼時,將執行類似的一致性、安全性和可見性檢查。它還發出裝箱/拆箱等程式碼。但是,它只需要做一次這些事情,然後可以保證程式碼可以安全執行。這使得實際的方法呼叫是一個非常便宜的操作(載入參數並跳轉到方法地址)。

相反,每次呼叫RuntimeMethodInfo.Invoke(因此呼叫GetValue/ SetValue)都需要重複所有工作,因為上下文——參數、實例和返回類型的用法——是未知的。這可能就是它如此緩慢的原因。

關於您可能缺少的內容:如果您發出自己的屬性呼叫委託,您當然需要自己處理裝箱/拆箱、引用/輸出參數等。

引用自:https://stackoverflow.com/questions/12767091