这应该是这个文章的最终版本了,期间犯了不少错误,也学习到了不少东西。
不多说了,直接上代码。还是我最后的测试结果,代码很简单,不解释了。
1 Stopwatch watch1 = new Stopwatch(); 2 3 watch1.Start(); 4 for ( int i = 0 ; i < 1000000 ; i ++ ) 5 { 6 Activator.CreateInstance( typeof (Class1)); 7 } 8 9 watch1.Stop(); 10 Console.WriteLine( " Activator.CreateInstance " ); 11 Console.WriteLine(watch1.Elapsed.ToString()); 12 13 watch1.Reset(); 14 watch1.Start(); 15 for ( int i = 0 ; i < 1000000 ; i ++ ) 16 { 17 GetCache.InstanceCacheEx.InstanceCache( typeof (Class1)); 18 } 19 watch1.Stop(); 20 Console.WriteLine( " Expression.CreateInstanceEx " ); 21 Console.WriteLine(watch1.Elapsed.ToString()); 22 23 24 watch1.Reset(); 25 watch1.Start(); 26 for ( int i = 0 ; i < 1000000 ; i ++ ) 27 { 28 new Class1(); 29 } 30 watch1.Stop(); 31 Console.WriteLine( " Direct CreateInstance " ); 32 Console.WriteLine(watch1.Elapsed.ToString());
表达式树构建和缓存:
1 public class InstanceCachesEx 2 { 3 private Dictionary < Type, Func < object >> dicEx = new Dictionary < Type, Func < object >> (); 4 public object InstanceCache(Type key) 5 { 6 7 Func < object > value = null ; 8 9 if (dicEx.TryGetValue(key, out value)) 10 { 11 return value(); 12 } 13 else 14 { 15 value = CreateInstance(key); 16 dicEx[key] = value; 17 return value(); 18 } 19 } 20 21 static Func < object > CreateInstance(Type type) 22 { 23 NewExpression newExp = Expression.New(type); 24 Expression < Func < object >> lambdaExp = Expression.Lambda < Func < object >> (newExp, null ); 25 Func < object > func = lambdaExp.Compile(); 26 return func; 27 } 28 } 29 30 public static class GetCache 31 { 32 static GetCache() 33 { 34 InstanceCacheEx = new InstanceCachesEx(); 35 } 36 37 public static InstanceCachesEx InstanceCacheEx { get ; set ; } 38 }
测试结果:
Activator.CreateInstance: 00 : 00 : 00.2221068 Expression.CreateInstanceEx: 00 : 00 : 00.0845797 Direct CreateInstance 00 : 00 : 00.0071313
之所以这么测试,是因为Activator.CreateInstance()方法使用了缓存机制,所以对于表达式树创建对象也使用了缓存,没有新东西,只是一个总结而已。至于为什么Activator.CreateInstance方法创建对象比用表达式创建对象要慢, (友情提示:或许评论能带给你更多的东西呦)