LDARG_0

.........

new的原罪

一直以为在开发阶段能够直接调用的,速度而言一定是最优秀的,因为总比后期通过反射之类来调用来得快吧.

 

下面请看一个SB的例子,重新编译以后,这个类在创建100,000,000实体时居然耗费了16秒的时间:

 

	internal class CreateWithNew<T> : EntityCreator<T> where T : new()
	{
		public override T Create()
		{
			return new T();
		}
	}//此SB相当荣幸的以为这个调用速度一定是最快的,怎么的也是编译级别的吧

  

 

奶奶的,居然还不如之前的解决方案:(创建100,000,000实体约4秒)

			/// <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()

 

于是果断修改成这样:

						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,我心里平衡了.

 

 

posted on 2014-02-28 09:25  sumok  阅读(256)  评论(0编辑  收藏  举报

导航