亲宝软件园·资讯

展开

详解C#实例化对象的三种方式及性能对比

背过手 人气:0

前言

做项目过程中有个需求要实例化两万个对象并添加到List

中,这个过程大概需要1min才能加载完(传参较多),于是开启了代码优化之旅,再此记录。

首先想到的是可能实例化比较耗时,于是开始对每种实例化方式进行测试,过程如下

实例化方式

1、用 New 关键字实例化一个类

2、用 Activator 实例化一个类

3、用 Assembly 实例化一个类

代码实现

测试环境:

vs2019 .NET Framework 4.7

Intel Core i7-10510U CPU

首先定义一个类Person

public class Person 
{ 
 public Person()
 {
 }
 public Person(string name)
 {
  Name = name;
 }
 public string Name { get; set; }
}

我们先在无参的构造函数中实例化,每种方式进行十次,每次实例化十万次,代码如下

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");
   Console.Write("InstanceByNew".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Person person = null;
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
     person = new Person();
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.Write("InstanceByActivator".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Type type = Type.GetType("ConsoleApp1.Person");
    Person person = null;

    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
    {
     object obj = Activator.CreateInstance(type);
     person = obj as Person;
    }
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.Write("InstanceByAssembly".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Assembly assembly = Assembly.Load("InstancePerformance");
    Person person = null;

    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
    {
     object obj = assembly.CreateInstance("ConsoleApp1.Person");
     person = obj as Person;
    }
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.ReadKey();
  }

执行结果如下:

然后来看下有参构造函数中实例化的代码和结果

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");
   Console.Write("InstanceByNew".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Person person = null;
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
     person = new Person("Test"+j);
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.Write("InstanceByActivator".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Type type = Type.GetType("ConsoleApp1.Person");
    Person person = null;

    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
    {
     object obj = Activator.CreateInstance(type,new object[]{"Test"+j});
     person = obj as Person;
    }
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.Write("InstanceByAssembly".PadRight(20));
   for (int i = 1; i <= 10; i++)
   {
    Assembly assembly = Assembly.Load("InstancePerformance");
    Person person = null;

    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int j = 0; j < 100000; j++)
    {
     object obj = assembly.CreateInstance("ConsoleApp1.Person", true, System.Reflection.BindingFlags.Default, null, new []{"Test"+j}, null, null);
     person = obj as Person;
    }
    watch.Stop();
    Console.Write(watch.ElapsedMilliseconds.ToString().PadLeft(5));
   }
   Console.Write("\n");
   Console.ReadKey();
  }

执行结果如下:

 

结论

从上面的执行结果可以看出这三种方式的性能排序为

New > Activator > Assembly

但使用哪种方法还要视情况而定

后续

以上可以看出New性能最高,而我就是使用的New,问题还没解决,把问题指向判断List是否存在某元素上,于是开始测试List中的Contains, Exists, Any,Where。详情请点击.

加载全部内容

相关教程
猜你喜欢
用户评论