英文原文:https://www.jacksondunstan.com/articles/3805
注:原文写自2017年
一年前,我写了一篇文章,标题为使用 Unity 5.2 进行 Foreach 循环创建垃圾,并使用各种集合测试了 foreach:列表、字典、数组等。从那时起,Unity 有了新的 C# 编译器,并且发布了 5.6 版本。现在使用 foreach 安全吗?请仔细阅读,找出答案!
今天的文章只是对上一篇文章中相同的测试脚本的重新测试。我今天使用 5.6.0f3 进行了测试,而不是 Unity 5.2.2f1。所有代码和运行它的步骤仍然适用。
提醒一下,测试脚本在各种集合类型(例如列表)上使用 foreach 循环来查看是否创建了任何垃圾。然后,它运行另一个 foreach 循环以查看第二次是否创建任何垃圾,如果正在进行一些内部缓存,则可能不会出现这种情况。
现在来看巨大的结果表。我在右侧添加了“5.2 Total”列来显示之前的结果。
Dictionary<T>、HashSet<T>、LinkedList<T>、Queue<T> 和 Stack<T> 现在在第一个循环上创建相同的 8 或 16 字节更少的垃圾,并在之后的任何循环上创建零垃圾。这是个好消息,因为对于这些集合中的任何一个,都无法使用普通的 for 循环来代替 foreach。
SortedDictionary<TKey, TValue> 现在在第一个循环中减少 16 个字节的垃圾,在后续循环中减少 64 个字节的垃圾。它仍然是所有集合中最大的垃圾产生者,因此如果您要远离 GC,请尽量避免它。
最后是大消息:List<T> 不再产生任何垃圾!这是迄今为止最常见的集合,因此这对于我们 Unity 程序员来说是一个巨大的胜利!当然,有一个警告。为了使 foreach 循环不产生任何垃圾,您需要使用 List<T> 变量。您不能使用它实现的接口,例如 IEnumerable<T>,否则每个循环都会创建 40 字节的垃圾。通常你可以避免这种情况,如果你想利用无垃圾的 foreach,你应该这样做。
虽然所有其他收集类型都没有改变它们产生的垃圾量,但至少它们使用的垃圾量都不比 Unity 5.2 中的垃圾量多。所以今天我们只有好消息。如果您因为无法使用 for 而使用 foreach,那么您将不会像以前使用 Dictionary<T> 这样的常见集合创建那么多垃圾。使用 List<T> 您不会创建任何垃圾,因此不再需要与它们一起使用。