我的问题是这样的: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