快速创建对象而不是Activator.CreateInstance的(类型) [英] Fast creation of objects instead of Activator.CreateInstance(type)
问题描述
我想改善我们的应用程序的性能。我们有很多正在导致一些悲痛Activator.CreateInstance呼叫。
I'm trying to improve the performance of our application. We have a lot of Activator.CreateInstance calls that are causing some grief.
我们实例化了很多基于接口(ITabDocument)对类和环顾四周后,我想用这个code的:
We instantiate a lot of classes based on an interface (ITabDocument) and after looking around I thought of using this code:
在code是没有更好的比使用Activator.CreateInstance code,我们有(逸岸略低)。
The code is no better (infact marginally slower) than using the Activator.CreateInstance code we had.
public static Func<T> CreateInstance<T>(Type objType) where T : class, new()
{
var dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + objType.Name, objType, null, objType);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, objType.GetConstructor(Type.EmptyTypes));
ilGen.Emit(OpCodes.Ret);
return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));
}
我不知道这是为什么,我做的是:
I'm wondering why this is, all I'm doing is:
ITabDocument document = CreateInstance<ITabDocument>(Type.GetType("[Company].Something"));
有没有创造这将有助于上述目标的更好的办法?其一点很难,当你不能确定具体的类型。
Is there a better way of creating objects which would assist with the above? Its a little hard when you're not sure of the concrete type.
推荐答案
我没有这两者之间一些基准测试(我会写下来的最低限度的详细信息):
I did some benchmarking between these (I would write down the bare minimum details):
public static T Instance() //~1800 ms
{
return new T();
}
public static T Instance() //~1800 ms
{
return new Activator.CreateInstance<T>();
}
public static readonly Func<T> Instance = () => new T(); //~1800 ms
public static readonly Func<T> Instance = () =>
Activator.CreateInstance<T>(); //~1800 ms
//works for types with no default constructor as well
public static readonly Func<T> Instance = () =>
(T)FormatterServices.GetUninitializedObject(typeof(T)); //~2000 ms
public static readonly Func<T> Instance =
Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();
//~50 ms for classes and ~100 ms for structs
由于CD说编译前pression是最快的,并且幅度较大。除了所有方法(T)FormatterServices.GetUninitializedObject(typeof运算(T))
仅带默认构造函数的工作。
和缓存编译生成的委托是微不足道的,当你有每泛型类型的静态类。这样的:
And caching the compiled resultant delegate is trivial when you have a static class per generic type. Like:
public static class New<T> where T : new()
{
public static readonly Func<T> Instance = Expression.Lambda<Func<T>>
(
Expression.New(typeof(T))
).Compile();
}
请注意在新
约束。什么叫
MyType me = New<MyType>.Instance();
除类在存储器被加载在第一时间,执行将是最快的。
Except for the first time the class is being loaded in memory, the execution is going to be fastest.
要具有与默认构造函数和没有处理这两种类型的类,我参加了一个混合的方法,从这里 的:
To have a class that handles both types with default constructor and without, I took a hybrid approach, from here:
public static class New<T>
{
public static readonly Func<T> Instance = Creator();
static Func<T> Creator()
{
Type t = typeof(T);
if (t == typeof(string))
return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile();
if (t.HasDefaultConstructor())
return Expression.Lambda<Func<T>>(Expression.New(t)).Compile();
return () => (T)FormatterServices.GetUninitializedObject(t);
}
}
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
将处理的值类型也以高效的方式。
Will handle value types too in an efficient manner.
的注意(T)FormatterServices.GetUninitializedObject(T)
将失败字符串
。对于字符串因此特别处理到位返回空字符串。的
Note that (T)FormatterServices.GetUninitializedObject(t)
will fail for string
. Hence special handling for string is in place to return empty string.
这篇关于快速创建对象而不是Activator.CreateInstance的(类型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!