方案一:
使用RealProxy实现接口,并操作get、set
方案二:
使用Emit创建接口实现类,并使用DynamicMethod构造创建constructor,操作getset
方案三:
使用emit创建接口实现类,并用Activator.CreateInstance创建实例。操作getset
对比结果:
{
Pixysoft.Tools.CodeTimer.Initialize();
Pixysoft.Tools.CodeTimer.Time("proxy", 100000, delegate()
{
IHello2 proxy = Pixysoft.Tools.PojoHelper.GetPojo<IHello2>();
proxy.Name = "123123";
string name = proxy.Name;
});
Pixysoft.Tools.CodeTimer.Time("dproxy dynamic constructor", 100000, delegate()
{
IHello2 dproxy = ReflectionManager.CreatePojo<IHello2>();
dproxy.Name = "123123";
string dname = dproxy.Name;
});
Pixysoft.Tools.CodeTimer.Time("drproxy dynamic constructor", 100000, delegate()
{
IHello2 drproxy = (IHello2)Activator.CreateInstance(ReflectionManager.CreatePojoType(typeof(IHello2)));
drproxy.Name = "123123";
string dname = drproxy.Name;
});
}
结果:
proxy
Time Elapsed: 8,250ms
CPU time: 8,000,000,000ns
Gen 0: 765
Gen 1: 0
Gen 2: 0
dproxy dynamic constructor
Time Elapsed: 233ms
CPU time: 218,750,000ns
Gen 0: 48
Gen 1: 0
Gen 2: 0
drproxy reflection constructor
Time Elapsed: 453ms
CPU time: 421,875,000ns
Gen 0: 16
Gen 1: 0
Gen 2: 0
1 passed, 0 failed, 0 skipped, took 9.03 seconds (Ad hoc).
可以看到RealProxy的性能基本上就是垃圾。循环10000次,使用了 8秒钟!!!
而emit之后,在使用动态方法构造对象,时间提升了 35.4倍
如果使用反射创建对象,则和动态方法比较:233/453 = 接近2倍
可见动态emit的性能是非常优秀的!!!!
最后再帖一个更加详细的性能报告:
------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------
proxy 使用RealProxy创建对象
Time Elapsed: 8,197ms
CPU time: 8,000,000,000ns
Gen 0: 766
Gen 1: 0
Gen 2: 0
drproxy reflection constructor 使用emit构造接口实现,然后使用Activator反射创建对象
Time Elapsed: 449ms
CPU time: 453,125,000ns
Gen 0: 17
Gen 1: 0
Gen 2: 0
dproxy dynamic constructor 使用emit构造接口实现,使用dynamicmethod创建对象,保存在缓存中,每次查找
Time Elapsed: 222ms
CPU time: 203,125,000ns
Gen 0: 49
Gen 1: 0
Gen 2: 0
var proxy 同上,但是emit的结果保存在临时变量,而不搜索cache
Time Elapsed: 4ms
CPU time: 0ns
Gen 0: 3
Gen 1: 0
Gen 2: 0
direct 直接代码构造接口实例,然后直接创建对象。
Time Elapsed: 4ms
CPU time: 0ns
Gen 0: 2
Gen 1: 0
Gen 2: 0
1 passed, 0 failed, 0 skipped, took 9.08 seconds (Ad hoc).
值得关注的是最后3项对比。可以看见.net的Dictionary的性能也是非常一般,花费了接近50倍的时间去搜索缓存。