繁体   English   中英

最有效的方法,标签或列表 <GameObject> ?

[英]Most efficient way, Tags or List<GameObject>?

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

使用标签节省更多的内存,还是需要多个资源才能通过标签进行搜索?

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

要么

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

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

现在,如果Unity3D的人们尊重这些准则是一个辩论的问题,但是从方法的名称上,我已经可以看出它是有成本的,不应太轻率。

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

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

这取决于内存分配和垃圾回收,如果不进行测量,就无法确定哪个确实更快。

因此,我能给您的最好建议是一般性的。 每当您觉得需要增强代码性能时,就必须实际衡量您要改进的前后。

最好使用“城市”对象列表,并为循环做一个标准,以循环访问“城市”对象。 List仅保留对“ City”对象的引用,因此对内存的影响应最小-您可以使用GameObjects []数组代替List(这是FindGameObjectsWithTag返回的内容)。

使用填充的列表/数组而不是按标签搜索对性能更好,当然,您要显式指向对象而不是使用“魔术”字符串-如果稍后更改标签名称,则FindGameObjectsWithTag方法将无提示中断,因为它将不再找到任何对象。

另外,避免在Unity中使用foreach循环,因为这样很不幸会创建大量垃圾(Unity中的垃圾收集器不是很好,因此最好创建尽可能小的垃圾),而只需使用标准的for循环即可:

用简单的“ for”循环替换“ foreach”循环。 由于某种原因,每个“ foreach”循环的每次迭代都会生成24字节的垃圾内存。 一个简单的循环迭代10次就可以收集240字节的内存,这是无法接受的

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

您的代码示例是2个截然不同的事物。 一种是实例化一个列表,另一种是枚举从函数调用返回的IEnumerable。

我假设您的意思是遍历声明列表与遍历GameObject.FindObjectsWithTag()的返回值之间的区别;

将List作为成员变量存储在类中,将其填充一次,然后对其进行多次迭代,比对GameObject.FindObjectsWithTag进行多次迭代的效率更高。

这是因为您始终保留列表和对列表中对象的引用,而不必重新填充它。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM