我們使用Resources資料夾內資源, 常用步驟為:
- 使用Resources.Load將資源讀取至記憶體
- 使用Object.Instantiate將步驟1實例化
然而我們在開發時很容易遇到一種需求:頻繁的生成同一種資源(ex:子彈)
在這種情況下一直Resources.Load同一個物件是必要的嗎?效能開銷又是如何呢?
讓我們來看看以下測試範例
測試專案: https://github.com/GooKu/Unity2017Test.git
測試碼: https://github.com/GooKu/Unity2017Test/blob/master/Assets/ResourcesLoadTest/ResourceLoadTest.cs
測試scene: ResourcesLoadTest.unity
我們可以發現使用Dictionary取出存起來的資源幾乎沒什麼時間開銷,
而每次都用Resources.Load讀資源所花費的時間是其數十倍
在這種情況下一直Resources.Load同一個物件是必要的嗎?效能開銷又是如何呢?
讓我們來看看以下測試範例
測試專案: https://github.com/GooKu/Unity2017Test.git
測試碼: https://github.com/GooKu/Unity2017Test/blob/master/Assets/ResourcesLoadTest/ResourceLoadTest.cs
測試scene: ResourcesLoadTest.unity
環境資訊
CPU: i5-4460(3.2GHz)
VGA: AMD R7770-PMD1GD5
OS: Windows 10
Unity版本: 2017.1.0f3 Personal
Platform: PC Standalone
---------
此測試種使用了2種方法讀取Resources資料夾裡的3個不同prefab:
擊點對應按鈕同時讀取10000次3個測試資源, 得到的結果如下---------
此測試種使用了2種方法讀取Resources資料夾裡的3個不同prefab:
- 直接使用Resources.Load讀取
- 將Resources.Load的物件存進Dictionary裡, 要使用時再取出
操作方法 | 時間(ms) |
Resources.Load | 39 |
Dictionary | 1 |
我們可以發現使用Dictionary取出存起來的資源幾乎沒什麼時間開銷,
而每次都用Resources.Load讀資源所花費的時間是其數十倍
此結果為PC輸出版的測試時間, 直接在編輯器中測試時 Resources.Load的時間會少很多, 但仍為Dictionary的數倍
由此我們可以了解:
使用Dictionary作資源暫存會占用部分記憶體空間, 但可以有效的減少取出資源時的CPU開銷
因此適合用於容量不大但需要頻繁生成的資源
這便是常見的"以空間換時間"小技巧
//使用一個Dictionary來存Resources.Load的東西
private Dictionary<string, GameObject> m_dic = new Dictionary<string, GameObject>();
//物件創建口, 此例直接用prefab的名字當參數
private GameObject Create(string prefabName)
{
GameObject resource = null;
//嘗試從m_dic取出資源
if (!m_dic.TryGetValue(prefabName, out resource))
{
//如果找不到, 就Resources.Load一個
resource = Resources.Load<GameObject>(prefabName);
//並加入m_dic, 這樣之後就找的到了
m_dic.Add(prefabName, resource);
}
//創建實體
return GameObject.Instantiate(resource);
}
沒有留言:
張貼留言