字串

有人可能會說,Unity 中的資源佔用量比簡陋的字串要多,但它是早期修復的一個比較容易的方面。

字串操作構建垃圾

大多數字串操作都會構建很少量的垃圾,但如果在單次更新過程中多次呼叫這些操作,它就會堆積起來。隨著時間的推移,它將觸發自動垃圾收集,這可能導致可見的 CPU 峰值。

快取字串操作

請考慮以下示例。

string[] StringKeys = new string[] {
    "Key0",
    "Key1",
    "Key2"
};

void Update()
{
    for (var i = 0; i < 3; i++)
    {
        // Cached, no garbage generated
        Debug.Log(StringKeys[i]);
    }

    for (var i = 0; i < 3; i++)
    {
        // Not cached, garbage every cycle
        Debug.Log("Key" + i);
    }

    // The most memory-efficient way is to not create a cache at all and use literals or constants.
    // However, it is not necessarily the most readable or beautiful way.
    Debug.Log("Key0");
    Debug.Log("Key1");
    Debug.Log("Key2");
}

它可能看起來很愚蠢和多餘,但如果你正在使用 Shaders,你可能會遇到這些情況。快取金鑰將有所作為。

請注意,字串文字常量不會生成任何垃圾,因為它們會靜態注入程式堆疊空間。如果你在執行時生成字串並且保證每次都像上面的示例一樣生成相同的字串,則快取肯定會有所幫助。

對於每次生成的字串不相同的其他情況,沒有其他方法可以生成這些字串。因此,每次手動生成字串的記憶體峰值通常可以忽略不計,除非一次生成數萬個字串。

大多數字串操作都是 Debug 訊息

對 Debug 訊息執行字串操作,即。Debug.Log("Object Name: " + obj.name) 很好,在開發過程中無法避免。但是,確保不相關的除錯訊息不會在已釋出的產品中結束是很重要的。

一種方法是在除錯呼叫中使用 Conditional 屬性 。這不僅會刪除方法呼叫,還會刪除進入它的所有字串操作。

using UnityEngine;
using System.Collections;

public class ConditionalDebugExample: MonoBehaviour
{
    IEnumerator Start()
    {
        while(true)
        {
            // This message will pop up in Editor but not in builds
            Log("Elapsed: " + Time.timeSinceLevelLoad);
            yield return new WaitForSeconds(1f);
        }
    }

    [System.Diagnostics.Conditional("UNITY_EDITOR")]
    void Log(string Message)
    {
        Debug.Log(Message);
    }
}

這是一個簡化的例子。你可能希望花一些時間設計更完善的日誌記錄例程。

字串比較

這是一個小的優化,但值得一提。比較字串比人們想象的要多一些。系統將預設將文化差異考慮在內。你可以選擇使用簡單的二進位制比較,其執行速度更快。

// Faster string comparison
if (strA.Equals(strB, System.StringComparison.Ordinal)) {...}
// Compared to
if (strA == strB) {...}

// Less overhead
if (!string.IsNullOrEmpty(strA)) {...}
// Compared to
if (strA == "") {...}

// Faster lookups
Dictionary<string, int> myDic = new Dictionary<string, int>(System.StringComparer.Ordinal);
// Compared to
Dictionary<string, int> myDictionary = new Dictionary<string, int>();