天天看點

[Unity優化]減少gc

參考連結:

http://www.cnblogs.com/mrkelly/p/5391156.html#3415238

http://www.cnblogs.com/murongxiaopifu/p/4284988.html#GC

一.減少使用foreach

首先回顧一下IEnumerable和IEnumerator

public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }
           
public interface IEnumerator
    {
        bool MoveNext();
        object Current { get; }
        void Reset();
    }
           

如果一個集合要使用foreach進行周遊,那麼需要實作IEnumerable這個接口。

下面回到正題,測試一下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TestCSharp : MonoBehaviour {

    private List<int> list = new List<int>();
    private Dictionary<int, int> dict = new Dictionary<int, int>();
    private int sum;

	void Start () 
    {
        for (int i = 0; i < 1000; i++)
        {
            list.Add(i);
            dict.Add(i, i);
        }

        sum = 0;
        Profiler.BeginSample("ForList");
        for (int i = 0; i < list.Count; i++)
        {
            sum += i;
        }
        Profiler.EndSample();
        Debug.Log(sum);

        sum = 0;
        Profiler.BeginSample("ForeachList");
        foreach (var item in list)
        {
            sum += item;
        }
        Profiler.EndSample();
        Debug.Log(sum);

        sum = 0;
        Profiler.BeginSample("EnumeratorList");
        var listEnumerator = list.GetEnumerator();
        while (listEnumerator.MoveNext())
        {
            sum += listEnumerator.Current;
        }
        Profiler.EndSample();
        Debug.Log(sum);

        ///

        sum = 0;
        Profiler.BeginSample("ForDict");
        //字典可以看作兩個list,一個list存key,一個list存value
        //兩個list是一一對應的關系
        List<int> keys = new List<int>(dict.Keys);
        for (int i = 0; i < dict.Count; i++)
        {
            sum += dict[keys[i]];
        }
        Profiler.EndSample();
        Debug.Log(sum);

        sum = 0;
        Profiler.BeginSample("ForeachDict");
        foreach (var item in dict)
        {
            sum += item.Value;
        }
        Profiler.EndSample();
        Debug.Log(sum);

        sum = 0;
        Profiler.BeginSample("EnumeratorDict");
        var dictEnumerator = dict.GetEnumerator();
        while (dictEnumerator.MoveNext())
        {
            sum += dictEnumerator.Current.Value;
        }
        Profiler.EndSample();
        Debug.Log(sum);
	}
	
}
           
[Unity優化]減少gc

結論:從gc和速度來看,使用GetEnumerator()來周遊集合是最好的。這裡我建議使用for周遊list,使用GetEnumerator周遊字典。

二.減少使用引用類型

引用類型存放在記憶體堆上,當引用類型不再被使用時,就會觸發gc。

Ps:string是引用類型

繼續閱讀