一直以为在开发阶段能够直接调用的,速度而言一定是最优秀的,因为总比后期通过反射之类来调用来得快吧.
下面请看一个SB的例子,重新编译以后,这个类在创建100,000,000实体时居然耗费了16秒的时间:
|
1
2
3
4
5
6
7 |
internal
class CreateWithNew<T> : EntityCreator<T> where
T : new(){ public
override T Create() { return
new T(); }}//此SB相当荣幸的以为这个调用速度一定是最快的,怎么的也是编译级别的吧 |
奶奶的,居然还不如之前的解决方案:(创建100,000,000实体约4秒)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 |
/// <summary>/// 根据参数的类型,创建一个句柄,这个句柄可以根据对应的参数列表创建指定的实例/// </summary>/// <param name="parameterTypes">参数类型列表</param>/// <returns>用于创建实例的句柄</returns>private
static Func<object[], TType> GenerateCreateInstanceHandler(Type[] parameterTypes){ Type type = typeof(TType); if
(type.IsSealed && type.IsAbstract) { throw
new NotSupportedException(string.Concat("不支持用于创建静态类型的实例:", Reflector.GetTypeName(type))); } if
(type.IsArray || type.IsEnum || type.IsGenericTypeDefinition || type.IsGenericParameter) { throw
new NotSupportedException(string.Concat("不支持用于创建数组,枚举,泛型定义,泛型参数的实例:", Reflector.GetTypeName(type))); } if
(type.IsNotPublic && (type.IsInterface || type.IsAbstract)) { throw
new NotSupportedException(string.Concat("不支持用于创建非公开的接口及抽象类型的实例:", Reflector.GetTypeName(type))); } //if (type.IsAbstract || type.IsInterface) //{ // TypeFactory factory = TypeFactory.Create(type); // factory.ImplementBase(); // type = factory.CreateType(); //} ConstructorInfo constructor = Reflector.GetConstructor(type, parameterTypes); DynamicMethodFactory<Func<object[], TType>> method = DynamicMethodFactory<Func<object[], TType>>.Create("CreateInstance"); /* * If found match constructor, then invoke it. * Else if found any constructor, use default parameters. */ MethodInfo convert = new
Func<object[], int, object>(GetParameter<object>).Method.GetGenericMethodDefinition(); if
(constructor != null) { #region Use a match constructor to create a new instance ParameterInfo[] parameters = constructor.GetParameters(); if
(type.IsClass) { int
len = parameterTypes.Length; for
(int
i = 0; i < len; i++) { ParameterInfo p = parameters[i]; method.LoadArg(0).Load(i); method.Call(convert.MakeGenericMethod(p.ParameterType)); } method.New(constructor).Return(); } else { LocalBuilder result = method.Declare(type); method.LoadVarAddr(result); int
len = parameterTypes.Length; for
(int
i = 0; i < len; i++) { ParameterInfo p = parameters[i]; method.LoadArg(0).Load(i); method.Call(convert.MakeGenericMethod(p.ParameterType)); } method.Call(constructor); method.LoadVar(result).Return(); } #endregion } else { method.LoadDefault<TType>().Return(); } return
method.Delegation;} |
奶奶的 ,抽象类居然被委托打败了,我很想学着穿越小说里面的SB配角大喊一声:怎么可能
于是开始分析,我X他娘的,居然发现NEW()被解释成了这个,他妈的这还不如直接反射算了
System.Activator.CreateInstance()
于是果断修改成这样:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
if (con.IsPublic && type.IsPublic){ Type parent = typeof
(EntityCreator<T>); TypeFactory factory = TypeFactory.Create(parent); factory.DefineOverride(parent.GetMethod("Create"), m => { m.New(con).Return(); }); Type creator = factory.CreateType(); Createor = Reflector.CreateInstanceAs<EntityCreator<T>>(creator);}else{ Createor = new
CreateWithPrivateNew<T>();} |
接下来表现如何?
2.6秒!!!
OK,我心里平衡了.
原文:http://www.cnblogs.com/exfx/p/3572861.html