C#例項化物件的三種方式及效能對比
阿新 • • 發佈:2020-12-10
## 前言
做專案過程中有個需求要例項化兩萬個物件並新增到List中,這個過程大概需要1min才能載入完(傳參較多),於是開啟了程式碼優化之旅,再此記錄。
首先想到的是可能例項化比較耗時,於是開始對每種例項化方式進行測試,過程如下
## 例項化方式
**1、用 New 關鍵字例項化一個類**
**2、用 Activator 例項化一個類**
**3、用 Assembly 例項化一個類**
## 程式碼實現
> 測試環境:
> vs2019 .NET Framework 4.7
> Intel Core i7-10510U CPU
首先定義一個類Person
```csharp
public class Person
{
public Person()
{
}
public Person(string name)
{
Name = name;
}
public string Name { get; set; }
}
```
我們先在無參的建構函式中例項化,每種方式進行十次,每次例項化十萬次,程式碼如下
```csharp
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();
}
```
執行結果如下:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201210184231897.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI4Njg0MDE3,size_16,color_FFFFFF,t_70)
然後來看下有參建構函式中例項化的程式碼和結果
```csharp
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();
}
```
執行結果如下:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201210184656480.png)
## 結論
從上面的執行結果可以看出這三種方式的效能排序為
==New > Activator > Assembly==
但使用哪種方法還要視情況而定
## 後續
以上可以看出New效能最高,而我就是使用的New,問題還沒解決,把問題指向判斷List是否存在某元素上,於是開始測試List中的Contains, Exists, Any,Where。[詳情請點選](https://www.cnblogs.com/ziqinchao/p/14116939.html).