我的問題是這樣的:ConstructorInfo.Invoke的DynamicMethod,我需要考慮什麼?
如果我要建立一個DynamicMethod對象,對應於ConstructorInfo.Invoke電話,做什麼類型的IL我需要,以實現應對所有(或大部分)類型當我能保證在我打電話之前要傳遞正確的類型和數量的參數?
背景
我對我的我的IoC容器的第3次迭代,目前做了一些分析,以找出是否有任何方面,我可以很容易刮掉大量的時間正在使用。
我注意到的一件事是,當解析爲一個具體類型時,最終我最終調用了一個構造函數,使用ConstructorInfo.Invoke,傳入一個我已經計算出來的參數數組。
我注意到的是,invoke方法有很多開銷,我想知道這是否只是我做的同樣的檢查的不同實現。例如,由於我有構造函數匹配代碼,爲了找到一個匹配的構造函數,用於我傳入的預定義的參數名稱,類型和值,這個特定的調用調用不會以某種方式結束它應該能夠以正確的順序,正確的類型和適當的值處理正確數量的參數。
在做包含萬個電話給我解決方法的分析會話,然後用DynamicMethod實現模仿調用調用替換它,仿形時序是這樣的:
- ConstructorInfo.Invoke:1973ms
- DynamicMethod的:93ms
這佔了20%左右這個分析應用程序的總運行時間。換句話說,通過使用相同的DynamicMethod替換ConstructorInfo.Invoke調用,我可以在處理基本的工廠作用域服務(即所有解析調用以構造函數調用結束)時削減20%的運行時間。
我認爲這是相當可觀的,並且需要仔細研究在此上下文中爲構造函數構建穩定的DynamicMethod生成器的工作量。
所以,動態方法將接受一個對象數組,並返回構造的對象,並且我已經知道有問題的ConstructorInfo對象。
因此,它看起來像動態方法會由以下的IL:
l001: ldarg.0 ; the object array containing the arguments
l002: ldc.i4.0 ; the index of the first argument
l003: ldelem.ref ; get the value of the first argument
l004: castclass T ; cast to the right type of argument (only if not "Object")
(repeat l001-l004 for all parameters, l004 only for non-Object types,
varying l002 constant from 0 and up for each index)
l005: newobj ci ; call the constructor
l006: ret
還有什麼我需要考慮?
注意,我知道,創建動態方法運行在「減少訪問模式」的應用程序(有時大腦就不會放棄這些條款)時,可能會無法使用,但在這種情況下,我可以很容易地檢測並且像以前一樣調用原始的構造函數,開銷和所有。
所以基本上,因爲我的Type對象的每個參數,如果Type.IsValueType返回,而不是castclass TYPE真的,我用unbox.any TYPE呢? – 2009-12-29 19:01:17
是的,這應該足以涵蓋所有參數類型。 – 2009-12-29 21:17:14
謝謝,我會添加一堆單元測試來驗證我能想到的所有組合,但是這看起來可能只是工作:) – 2009-12-29 21:54:53