快速创建对象而不是 Activator.CreateInstance(type)

2023-11-25

我正在努力提高应用程序的性能。我们有很多Activator.CreateInstance电话引起了一些悲伤。

我们基于接口实例化了很多类(ITabDocument),环顾四周后,我想到使用这段代码:

该代码并不比使用Activator.CreateInstance我们有代码。

    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>));
    }

我想知道为什么会这样,我所做的就是:

ITabDocument document = CreateInstance<ITabDocument>(Type.GetType("[Company].Something"));

有没有更好的方法来创建有助于完成上述任务的对象?当您不确定具体类型时,这有点困难。


我在这些之间做了一些基准测试(我会写下最基本的细节):

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 所说,编译表达式是最快的,而且差距很大。所有方法除了(T)FormatterServices.GetUninitializedObject(typeof(T)) 仅适用于具有默认构造函数的类型。

当每个泛型类型都有一个静态类时,缓存编译后的结果委托就很简单了。喜欢:

public static class New<T> where T : new()
{
    public static readonly Func<T> Instance = Expression.Lambda<Func<T>>
                                              (
                                               Expression.New(typeof(T))
                                              ).Compile();
}

请注意new约束。打电话任何事

MyType me = New<MyType>.Instance();

除了第一次将类加载到内存中之外,执行速度将是最快的。

为了有一个类可以处理带默认构造函数和不带默认构造函数的两种类型,我采用了混合方法,从这里:

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;
}

也将以有效的方式处理值类型。

注意(T)FormatterServices.GetUninitializedObject(t)将会失败string。因此,对字符串进行特殊处理以返回空字符串。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速创建对象而不是 Activator.CreateInstance(type) 的相关文章

  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 为什么这个没有特殊字符的正则表达式会匹配更长的字符串?

    我正在使用此方法来尝试查找匹配项 例如 Regex Match A2 TS OIL TS OIL RegexOptions IgnoreCase Success 我得到了真实的结果 我很困惑 我认为这应该返回 false 因为模式中没有特殊
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • vs2008 c#:Facebook.rest.api如何使用它来获取好友列表?

    如何在此基础上取得进一步的进步 获取好友列表的下一步是什么 string APIKey ConfigurationManager AppSettings API Key string APISecret ConfigurationManag
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐

  • 将 python 与更快的语言混合以在 GAE 中进行优化

    我是 Python 和 GAE 领域的新手 我有一个问题 对于 Python 通常的方法是仅在需要时优化代码 修复更紧急的瓶颈 实现这一目标的方法之一是用 C 重写程序最关键的部分 通过使用 GAE 我们会永远失去这种可能性吗 自从谷歌的G
  • C 结构中的灵活数组成员

    引用 C std 第 6 7 2 1 节 struct s int n double d 这是一个有效的结构声明 我正在寻找这种语法的一些实际用途 准确地说 这个结构与将 double 作为第二个元素相比有何不同 或者这是 你可以用多种方式
  • JAXB-WS - 使用 @WebMethod 强制字段

    我有一个 WebMethod 调用 WebMethod public int cancelCampaign String campaignId String reason 我想将 CampaignId 字段标记为必填字段 不知道该怎么做 我
  • 如何使用 ssh 导出 mysql 数据库?

    我可以在 ssh 上使用哪些命令来使用 SSH 导出 下载 mysql 数据库 To 使用 SSH 导出 mysql 转储 执行以下命令 mysqldump u username p dbname gt db dump sql userna
  • 为什么 __init__.py 没有被调用?

    我使用的是 Python 2 7 并有以下文件 init py aoeu py init py有以下内容 aoeu aoeuaoeu aoeuaoeuaoeu 所以我希望当Python尝试加载时运行aoeu py会出错 init py 但事
  • 使用 Angular2 将 HTML 从服务器插入 DOM(Angular2 中的常规 DOM 操作)[重复]

    这个问题在这里已经有答案了 我想将从服务器检索到的一些 HTML 插入到 angular2 中的 DOM 元素中 我似乎无法找出最好 正确的方法来做到这一点 我不能只是将 my data 放入模板中 因为 Angular 2 会自动转义 H
  • 本地作用域与 __init__.py 内的相对导入

    我注意到了asyncio init py从Python 3 6开始使用以下构造 from base events import all base events all The base events符号没有在源代码中的任何地方导入 但模块仍
  • HABTM 重复记录

    我有2个型号Game Theme并且它们有一个 has and belongs to many 关联 我尝试了很多解决方案来防止重复记录games themes表 但没有解决方案有效 问题是 games themes是一个表 但它不是一个模
  • 创建项目时 XCode 6.0.1 错误:文件“排除”不存在

    当我在 XCode 6 0 1 中创建新项目时 收到以下错误消息 文件 排除 不存在 它似乎只影响文件的版本控制 即生成的存根文件在项目创建后不会提交到 github 中 什么会导致这个问题 对我来说 这个问题是因为我之前创建了一个同名的项
  • 如何使 Backbones toJSON 函数包含子模型和集合?

    我有一些模型不仅包含基本数据属性 而且可能具有一个或两个包含另一个模型对象的属性 一直没问题 但现在我想打电话 myRootModel toJSON 我注意到它不会在我尝试调用 toJSON 的模型中的其他模型上调用 toJSON 有没有办
  • 在没有 livereload 的情况下构建时,文件路径中缺少“android_asset/www/”

    我正在开发一个离子应用程序 ionic v1 7 13 cordova v5 4 1 当我跑步时 ionic run android l 一切正常 我的所有项目文件都已正确加载 当我尝试在没有 livereload 的情况下运行时 就会出现
  • 如何在 Blazor WebAssembly 中使用 SQLite?

    对于 Blazor WebAssembly 我提出了使用 SQLite 的想法 这个问题提到这是不可能的 是否可以在 Blazor WebAssembly 中使用 SQLite 如果可以 如何使用 从 NET 6 开始 您可以在 Blazo
  • UIColor 与 IB 颜色(颜色配置文件问题)

    我正在使用 XCode 8 2 1 我刚刚了解了颜色配置文件 并且 RGB 值不是通用的 但仍然无法理解如何在代码中使其正确 在 Interface Builder 中 我为标签选择了预定义的 深灰色 通用 RGB 配置文件中的值为 85
  • 如何获取父基类对象 super.getClass()

    我对 Java 有一点问题 作为一名 C 程序员 我有2个相关课程 public class Patient public class PatientPersistent extends Patient public void foo Sy
  • 何时以及何时不安装到 GAC 中?

    什么时候应该安装到 GAC 中 什么时候不应该安装 我实际上指的是在客户购买了我们的产品后安装在他们的机器上 我有一个程序集仅用于我的一个应用程序 GAC 或非 GAC 我有一个所有应用程序共享的程序集 GAC 或非 GAC 我所有的应用程
  • tensorflow 每次运行发现多个图形事件

    我正在为在本地模式下运行的机器学习引擎实验加载张量板 并收到以下警告 Found more than one graph event per run or there was a metagraph containing a graph d
  • 在 JavaScript 中渲染一系列图像,就像视频一样

    我正在尝试使用 JavaScript 中的图像流合成视频 问题是 视频 要么是不稳定的 这是通过使用某种缓冲区来解决的 然而现在的问题是图像的下载速度实际上远远快于渲染速度 如果您的图像源会发生变化 例如 IP 摄像机 您可以尝试下面的示例
  • “time.sleep()”在带有使用“end”属性的打印函数的 for 循环中不起作用吗?

    所以 我最近刚刚学习 python 并且正在玩一些代码 我想在循环中打印一些没有换行符的字符 但有一些延迟 我在 for 循环中使用了 time sleep 函数 但是 它所做的只是延迟输出在循环中所花费的总时间 然后打印出字符 我确实在没
  • 谁在 Pylons 在线

    我目前有一个 Pylons 应用程序 运行基本的用户系统设置 我想尝试创建一个小部件来显示当前登录该网站的用户 我不确定我应该如何处理这个问题 我不确定 pylons 会话是否处于活动状态取决于用户是否实际上位于网络应用程序页面上 因此我正
  • 快速创建对象而不是 Activator.CreateInstance(type)

    我正在努力提高应用程序的性能 我们有很多Activator CreateInstance电话引起了一些悲伤 我们基于接口实例化了很多类 ITabDocument 环顾四周后 我想到使用这段代码 该代码并不比使用Activator Creat