在我的游戏中,我可以使用游戏对象或标签列表进行迭代,但我更喜欢知道什么是最有效的方法。
使用标签或统一节省更多内存需要很多资源才能按标签进行搜索?
public List<City> _Citys = new List<City>();
或
foreach(GameObject go in GameObject.FindGameObjectsWithTag("City"))
答案 0 :(得分:2)
根据Microsoft的C#API规则,Find*
或Count*
等动词表示活动代码,而Length
等术语代表不需要代码执行的实际值。
现在,如果Unity3D人员尊重这些指导方针是一个有争议的问题,但从方法的名称来看,我已经知道它有成本,不应该太过淡淡。
另一方面,你的问题是关于表现,而不是正确性。这两种方式都是正确的本身,但其中一种应该具有更好的性能。
因此,重构性能的主要规则是: MEASURE 。
这取决于内存分配和垃圾收集,如果不进行测量,就无法确定哪个更快。
所以我能给你的最好的建议很一般。每当您觉得需要提高代码性能时,您必须实际测量您要改进的内容。之前和之后。
答案 1 :(得分:0)
您最好使用City对象列表并执行标准for循环来迭代“City”对象。 List只是简单地保存对'City'对象的引用,因此对内存的影响应该是最小的 - 你可以使用GameObjects []数组而不是List(这是FindGameObjectsWithTag返回的)。
使用填充的List / Array而不是使用Tags进行搜索更好,当然你明确地指向一个对象而不是使用'magic'字符串 - 如果稍后更改标记名称,那么FindGameObjectsWithTag方法将无声地中断,因为它将不再找到任何对象。
编辑:正如pid的回答中所提到的 - 措施。您可以使用内置的Unity Profiler检查内存使用情况:http://docs.unity3d.com/Manual/ProfilerMemory.html用简单的“for”循环替换“foreach”循环。出于某种原因,每个“foreach”循环的每次迭代都会生成24字节的垃圾内存。一个简单的循环迭代10次,剩下240字节的内存准备收集,这是不可接受的
答案 2 :(得分:0)
您的代码示例是两个截然不同的东西。一个是实例化一个列表,一个是枚举从函数调用返回的IEnumerable。
我假设你的意思是迭代你声明的列表与迭代GameObject.FindObjectsWithTag()的返回值之间的区别;在这种情况下;
将List存储为类中的成员变量,填充一次然后多次迭代它比迭代GameObject.FindObjectsWithTag几次更有效。
这是因为您始终保持列表和对列表中对象的引用,而无需重新填充它。
GameObject.FindObjectsWithTag将搜索整个对象层次结构,并编译它找到的符合搜索条件的所有对象的列表。每次调用该函数时都会执行此操作,因此即使它找到的对象数量仍与搜索您的层次结构相同,也会产生额外的开销。
说实话,您可以使用GameObject.FindObjectWithTag使用List对象缓存结果,前提是返回的对象数量不会改变。 (比如说你没有实例化或破坏任何这些对象)