2017-05-24 130 views

回答

1

在Unity 4.x和下面,所述高速緩存的方法將是顯著更快。在這些版本中,MonoBehaviour.transform和MonoBehaviour.gameObject實際上並不是字段;相反,「引擎蓋下」他們表現得像附屬存取器的屬性。

因此,訪問gameObject屬性將通過訪問器對Component.get_gameobject()進行方法調用。當然,方法調用自然會比簡單的內存訪問造成更多的開銷。 (變換更糟;顯然訪問者實際上調用了GetComponent方法來返回值!)

這就是爲什麼您經常會看到經驗豐富的Unity開發人員緩存這些值。

我很有權利在Unity 5中優化此流程以獲得更好的性能;使用內置屬性仍然會產生非常小的開銷,但據報道它是微不足道的。

來源:https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/

1

我假定高速緩存可變比使用gameObject變量從Component類和一個簡單的測試更快證明是正確的。這是因爲緩存它會爲您提供參考,而不是使用gameObject,它使用get訪問器返回引用。不知道是否獲取引用需要本地函數調用,但這是一種可能性。使用get訪問器比直接引用訪問慢。

比方說,您有100萬個腳本調用gameObject.activeSelf或通過緩存版本_GameObject.activeSelf

測試結果:

遊戲對象:54毫秒

緩存_GameObject:30毫秒的

軟件/硬件測試:

  • 統一5.6.0f3
  • 的Windows 10 Pro的
  • MacBookPro11,4
  • 16 GB RAM

什麼關係呢?

在一個正常的應用程序,也許不是。在一場比賽中,是的。根據遊戲的種類,從遊戲中移除24ms是一個很好的改進。

測試腳本:

public GameObject _GameObject; 

void Start() 
{ 
    Application.runInBackground = true; 

    int iterations = 1000000; 

    //TEST 1 
    Stopwatch stopwatch1 = Stopwatch.StartNew(); 
    for (int i = 0; i < iterations; i++) 
    { 
     bool active = gameObject.activeSelf; 
    } 
    stopwatch1.Stop(); 

    //TEST 2 
    Stopwatch stopwatch2 = Stopwatch.StartNew(); 
    for (int i = 0; i < iterations; i++) 
    { 
     bool active = _GameObject.activeSelf; 
    } 
    stopwatch2.Stop(); 
    //SHOW RESULT 
    WriteLog(String.Format("gameObject: {0}", stopwatch1.ElapsedMilliseconds)); 
    WriteLog(String.Format("Cached _GameObject: {0}", stopwatch2.ElapsedMilliseconds)); 
} 

void WriteLog(string log) 
{ 
    UnityEngine.Debug.Log(log); 
}