• .NET C# 三种实例化一个类的方式的性能比较


    本文内容

    • 实例化一个类的方式
    •     用 New 关键字实例化一个类
    •     用 Activator 实例化一个类
    •     用 Assembly 实例化一个类
    • 性能比较
    •     环境
    •     比较
    •     分析
    •     代码

    在开发应用程序时,能够动态实例化一个类很有用。给出类的一个字符串名称,就能够创建这个类的一个实例。若这些需要实例化的类都继承同一个接口(如本例的 IPerson),那么实例化的 object 类型转换后可以赋值给这个接口。这很方便。否则,就得用 swtich-case 语句(估计会很长)。

    那么,接下来的问题,实例化一个类的性能如何。

    之前,我用 Assembly 较多,写本文后,发觉好像不妥。

      实例化一个类的方式


      • 用 New 关键字实例化一个类

      New 关键字用于创建对象和调用构造函数。是实例化一个类最常见的方式。

      • 用 Activator 实例化一个类

      Activator 用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。其 CreateInstance 方法创建在程序集中定义的类型的实例。

      • 用 Assembly 实例化一个类

      Assembly 表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行库应用程序构造块。该类可以加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。

      加载程序集的推荐方式是使用 Load 方法。GetType 方法可用于在程序集中搜索特定类型。CreateInstance 方法可用于在程序集中搜索和创建类型的实例。

      本文通过这三种方式来创建一个类的实例。

      性能比较

      环境

      • VS 2008 .NET Framework 3.5
      • Intel CPU Duo  T5450 1.66GHz
      • Memory 2G
      比较

      假设,Demo 中使用的类都在同一个程序集。

      using System;
       
      namespace InstancePerformance
      {
          class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine("实例化一个类的性能比较(单位:毫秒)");
                  Console.Write("                    ");
                  for (int i = 1; i <= 10; i++)
                      Console.Write("{0:G}", i.ToString().PadLeft(5));
                  Console.Write("\n");
                  // New Key
                  Console.Write("InstanceByNew".PadRight(20));
                  for (int i = 1; i <= 10; i++)
                      InstanceByNewKey.Create();
                  Console.Write("\n");
                  // Activator
                  Console.Write("InstanceByActivator".PadRight(20));
                  for (int i = 1; i <= 10; i++)
                      InstanceByActivator.Create();
                  Console.Write("\n");
                  // Assembly
                  Console.Write("InstanceByAssembly".PadRight(20));
                  for (int i = 1; i <= 10; i++)
                      InstanceByAssembly.Create();
                  Console.Write("\n");
       
                  Console.ReadKey();
              }
          }
      }

      实例化一个类的性能比较

      其中,

      • InstanceByNewKey.Create() 用 New 关键字实例化一个类;
      • InstanceByActivator.Create() 用 Activator 实例化一个类;
      • InstanceByAssembly.Create() 用 Assembly 实例化一个类。

      在“代码”小节是这三个方法的实现代码。

      • 为了便于测试,时间不至于小得可怜,以上每个方法实例化十万次,也就是创建十万个对象。
      • 为了便于比较,对以上每个方法都调用 10 次。进行横向和纵向比较。

       1

      分析

      由上图可以看出,用 Activator 实例化一个类最快;其次是用 New 关键字;最慢的是用 Assembly 实例化。Activator 比 用 New 都快。

      因此,若想动态实例化一个类,根据你的实际情况,尽量将需要实例化的类放在同一个程序集。

      代码

      代码段 1:IPerson 接口和 Person 类

      public class IPerson
      {
       
      }
      public class Person : IPerson
      {
          public string Name { get; set; }
       
          public Person()
          {
          }
          public Person(string name)
          {
              this.Name = name;
          }
      }

      代码段 2:使用 New 关键字实例化

      public class InstanceByNewKey
      {
          /// <summary>
          /// 直接调用
          /// </summary>
          public static void Create()
          {
              IPerson person = null;
              Stopwatch watch = new Stopwatch();
              watch.Start();
              for (int i = 0; i < 100000; i++)
                  person = new Person("My" + i);
              watch.Stop();
              Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
          }
      }

      另外,若该代码段写成如下,是没有必要的。其他代码段类似。

      Stopwatch watch = new Stopwatch();
      watch.Start();
      for (int i = 0; i < 100000; i++)
          IPerson person = new Person("My" + i);
      watch.Stop();
      Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));

      代码段 3:使用 Activator 实例化

      public class InstanceByActivator
      {
          /// <summary>
          /// 实例化反射
          /// </summary>
          public static void Create()
          {
              Type type = Type.GetType("InstancePerformance.Person");
              IPerson person = null;
       
              Stopwatch watch = new Stopwatch();
              watch.Start();
              for (int i = 0; i < 100000; i++)
              {
                  object obj = Activator.CreateInstance(type);
                  person = obj as IPerson;
              }
              watch.Stop();
              Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
          }
      }

      代码段 4:使用 Assembly 实例化

      public class InstanceByNewKey
      {
          /// <summary>
          /// 直接调用
          /// </summary>
          public static void Create()
          {
              IPerson person = null;
              Stopwatch watch = new Stopwatch();
              watch.Start();
              for (int i = 0; i < 100000; i++)
                  person = new Person("My" + i);
              watch.Stop();
              Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
          }
      }

      下载 Demo

    • 相关阅读:
      设计模式学习总结
      算法时间复杂度和空间复杂度表示
      SQLite简单使用
      接口,组合和继承的想法
      二叉树的学习
      Oracle 常用命令大汇总
      Oracle 最常用功能函数经典汇总
      oracle 常用command
      历史最牛演讲:Oracle总裁Yale演讲全文中英文对照
      深入abstract class和interface
    • 原文地址:https://www.cnblogs.com/liuning8023/p/2572073.html
    Copyright © 2020-2023  润新知