快速创建对象而不是Activator.CreateInstance的(类型) [英] Fast creation of objects instead of Activator.CreateInstance(type)

查看:2206
本文介绍了快速创建对象而不是Activator.CreateInstance的(类型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想改善我们的应用程序的性能。我们有很多正在导致一些悲痛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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆