最有效的方式,标签还是列表<GameObject>?



在我的游戏中,我可以使用游戏对象或标签的列表来迭代,但我更喜欢知道什么是最有效的方法。

使用标签节省更多内存还是统一需要许多资源才能按标签进行搜索?

public List<City> _Citys = new List<City>();

foreach(GameObject go in GameObject.FindGameObjectsWithTag("City")) 

您最好使用城市对象列表,并执行标准的for循环来迭代"城市"对象。List只是简单地保存对"City"对象的引用,所以对内存的影响应该是最小的——你可以使用GameObjects[]数组而不是List(FindGameObjectsWithTag返回的是List)。

为了提高性能,最好使用填充的List/Array,而不是按标记进行搜索,当然,您是明确指向对象,而不是使用"魔术"字符串——如果稍后更改标记名称,则FindGameObjectsWithTag方法将静默中断,因为它将不再查找任何对象。

此外,避免在Unity中使用foreach循环,因为这很不幸会产生很多垃圾(Unity中的垃圾收集器不太好,所以最好创建尽可能少的垃圾),而只使用循环的标准:

将"foreach"循环替换为简单的"for"循环。出于某种原因,每个"foreach"循环的每次迭代都会生成24字节的垃圾内存。一个简单的循环迭代10次,留下240字节的内存准备收集,这是不可接受的

EDIT:正如pid的答案-度量中所提到的。您可以使用内置的Unity探查器来检查内存使用情况:http://docs.unity3d.com/Manual/ProfilerMemory.html

根据Microsoft的C#API规则,Find*Count*等动词表示活动代码,而Length等术语表示不需要执行代码的实际值。

现在,Unity3D的人是否尊重这些指导方针是一个有争议的问题,但从方法的名称来看,我已经可以看出,这是有代价的,不应该太掉以轻心。

另一方面,你的问题是关于性能,而不是正确性。这两种方法本身都是正确的,但其中一种应该具有更好的性能。

因此,重构性能的主要规则是:MEASURE

这取决于内存分配和垃圾收集,如果不进行测量,就无法判断哪一个真正更快。

所以我能给你的最好的建议是一般性的。每当你觉得有必要提高代码的性能时,你必须实际衡量你将要改进的内容,无论是之前还是之后。

您的代码示例是两个截然不同的东西。一个是实例化列表,另一个是枚举函数调用返回的IEnumerable。

我假设你的意思是迭代你声明的列表和迭代GameObject.FindObjectsWithTag()的返回值之间的区别,在这种情况下;

将List存储为类中的成员变量,填充一次,然后对其迭代几次,比对GameObject.FindObjectsWithTag迭代几次更有效。

这是因为你一直保留你的列表和你对列表中对象的引用,而不必重新填充它

GameObject.FindObjectsWithTag将搜索您的整个对象层次结构,并编译与您的搜索条件匹配的所有对象的列表。这是在每次调用函数时完成的,因此即使它找到的对象数量与它仍然搜索层次结构的数量相同,也会有额外的开销。

老实说,你可以使用GameObject.FindObjectWithTag用List对象缓存你的结果,前提是返回的对象数量不会改变。(比如说你没有实例化或销毁任何这些对象)

相关内容

最新更新