[Unity/C#] 三種類別實體化方法的效能比較 - the Effectiveness of 3 Kinds of Creating Methods of Class

比較三種將類別實體化 (Create Instance) 的方法之效能差異:

  • 使用反射機制 (Reflection)
  • 使用 Activator 搭配已知型態 (Type)
  • 直接使用 new()

因為曾經看過反射機制 (Reflection) 需要大量消耗效能,但是在開發中為了便利與維護,C# 的反射機制 (Reflection) 是相當有用處的。

所以到底該不該使用反射機制 (Reflection) 在 Unity 的實際開發中呢?如果是要開發手機遊戲是否應該避開?於是做了次實際測試來確認。

測試用程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class BaseClass {}
public class TestInstanceEffection : MonoBehaviour {
public int TESTTIME = 10000000;
private BaseClass m_inst; private Type m_type = typeof(BaseClass);
void Start () {
float timer;
timer = Time.realtimeSinceStartup;
for (int i = 0; i < TESTTIME; i++) {
m_inst = Assembly.GetExecutingAssembly ().CreateInstance ("BaseClass") as BaseClass;
}
Debug.Log (string.Format("Assembly CreateInstance: {0}", Time.realtimeSinceStartup - timer));

timer = Time.realtimeSinceStartup;
for (int i = 0; i < TESTTIME; i++) {
m_inst = Activator.CreateInstance(m_type) as BaseClass;
}
Debug.Log (string.Format("Activator CreateInstance: {0}", Time.realtimeSinceStartup - timer));

timer = Time.realtimeSinceStartup;
for (int i = 0; i < TESTTIME; i++) {
m_inst = new BaseClass ();
}
Debug.Log (string.Format("Normal CreateInstance: {0}", Time.realtimeSinceStartup - timer));
}
}

測試環境使用 PC 來進行,Unity 版本為 5.5.0f3。

註:上方程式碼的測試並沒有精準的將大量使用捨棄物件造成的 GC 考慮進去

測試結果

instance1
instance2
instance3

以結果來說,三者的消能消耗大約是 50:20:1 但實際上,這段測試數據每個方法各自建立了一千萬個類別實體,以實際應用來說很難在短時間需要如此大量的實體化動作,所以不須要刻意去在意這點效能消耗。

結論是,將反射機制直接用於實際應用並不需要過度擔心效能,如有需要則放心使用即可。只要適量且適當地使用,每個方便的機制都是可以用於實際開發的。