本文內容 實例化一個類的方式 用 New 關鍵字實例化一個類 用 Activator 實例化一個類 用 Assembly 實例化一個類 性能比較 環境 比較 分析 代碼 在開發應用程式時,能夠動態實例化一個類很有用。給出類的一個字元串名稱,就能夠創建這個類的一個實例。若這些需要實例化的類都繼承同一個 ...
本文內容
- 實例化一個類的方式
- 用 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 次。進行橫向和縱向比較。
分析
由上圖可以看出,用 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));
}
}