如何减少Unity中List.Contain()引起的GC

时间:2019-09-09 05:28:30

标签: c# unity3d

我正在尝试减少Unity项目中的GC,这是以下代码,我想知道原因。

非常感谢你们:)

这是我从演示中提取的代码,我正在使用此数据“ Bineary Heap”结构来实现Astar算法

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

public class Test : MonoBehaviour
{
    Waypoint wp = new Waypoint();
    BinaryHeap<Waypoint> openls = new BinaryHeap<Waypoint>();
    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i < 400; i++)
        {
            UnityEngine.Profiling.Profiler.BeginSample("contain");
            openls.Contains(wp);    
            UnityEngine.Profiling.Profiler.EndSample();
        }
    }

    public class BinaryHeap<T> : IEnumerable<T> where T : IComparable<T>
    {
        private List<T> mHeap;

        public BinaryHeap() { this.mHeap = new List<T>(); }

        public void Insert(T data)
        {
            int size = mHeap.Count;
            mHeap.Add(data);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return mHeap.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return mHeap.GetEnumerator();
        }
    }

    public class Waypoint : IComparable<Waypoint>
    {
        public int id = 0;
        public int CompareTo(Waypoint p)
        {
            return 1;
        }
    }
}


这是Unity中的前途报告 https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

1 个答案:

答案 0 :(得分:1)

您的课程没有Contains方法,这意味着您正在使用LINQ的Contains扩展方法。那个家伙根本不知道您的班级内部有一个列表-它只有IEnumerable接口,这意味着它需要创建一个枚举器。每次调用分配的内存约为40B,这可能就是这个对象。

如果要避免这种分配,请编写自己的Contains方法。由于您已经在使用列表,因此只需在列表上调用Contains

public bool Contains(T obj) => mHeap.Contains(obj);

作为一个附带说明,装箱在这里无论如何都不起作用-您使用的是通用列表类,因此即使您使用的是值类型,也不会装箱。这就是为什么首先将泛型添加到C#的主要原因(尽管它们当然还有很多有用的功能)。