成都unity3D培训:程序丨Unity3D性能优化最佳实践(三):协程
Coroutines- 协程
Coroutine 运作方式和其他脚本程序不同,大多数的程序消耗只会出现在追踪报告里的单一位置,在特定的回呼被执行,但是 Coroutine会出现在 CPU 报告的两个不同地方。
所有在 Coroutine 里的初始化程序,从方法开始到第一次的 yield,这部分的追踪数据会出现在 Coroutine 启动的地方,通常是 StartCoroutine 被呼叫的地方。直接从从 Unity 回呼启动的 Coroutine(比如回传值宣告成 IEnumerator 的 Start)则会显示在各自的 Unity 回呼下。
所有剩下的 Coroutine程序,从第一次被继续执行到结束,都会出现在 Unity 主循环下的DelayedCallManager 里。
要知道为何会这样,就必须了解 Coroutine 的运作方式。
Coroutine 底下有个 C# 编译程序自动产生的类别的实例, 对程序设计师来说看起来像是一个普通的方法,但在实作上我们需要这个对象在每次呼叫之间保存这个 Coroutine 的状态。因为 Coroutine 中的局部变量(local-scope variables)在 yield 之间必须保有之前赋予的值,所以这些局部变量会提到先前所说的 C# 编译程序产生的类别,它的实例在 Coroutine 的执行结束之前会维持配置在堆积内存上(Heap memory)。这个对象也负责追踪 Coroutine 的执行状态:它会记住 Coroutine 在 yield 之后下一次该从哪边继续。
因此,启动一个 Coroutine 所引起的内存消耗同等于一个固定的成本加上这个 Coroutine 用到的局部变量总合的大小。
启动 Coroutine 的程序建构并呼叫这个自动生成对象上的方法,然后 Unity 的 DelayedCallManager 在 Coroutine的 yield 时给的条件(WaitForSeconds、WaitForFixedUpdate 之类的条件)满足时再次呼叫它。由于 Coroutine通常在其他 Coroutine 之外启动 ,这会让它们的执行消耗拆分成上述两个不同位置。

上图可以看到 DelayedCallManager 正重新呼叫几个不同的 Coroutine,像是 PopulateCharacters、AsyncLoad 和 LoadDatabase。
如果可以,尽可能用最少 Coroutine 做最多的事,虽然巢状 Coroutine(从 Coroutine 再产生 Coroutine)非常好维护也能维持程序简洁,但每次使用 Coroutine 就要配置新的追踪用对象,用越多Coroutine 代表内存消耗也越多。
如果 Coroutine 几乎每一帧都要执行,也没有用 yield 在需要长时间等待的操作上,改回用 Update 或LateUpdate 会比较好。尤其是对那种周期很长或是无穷的 Coroutine 更是如此。
要记得很重要的一点是 Coroutine「不是」线程(threads),Coroutine 里的同步(Synchronous)行为仍然是在主线程上执行的,因此如果你的目的是降低主线程在 CPU 上的消耗,就跟呼叫一般方法一样必须避免在 Coroutine 上面执行会卡住(Blocking)线程的操作。
Coroutine 还是最适合处理长时间的异步操作,比如等候 HTTP 传输、资源加载或是档案 I/O。
成都it培训哪家好,当然是成都达内培训,成都达内是一家专业的程序员培训机构,专注于成都嵌入式培训,成都web前端培训,成都.NET培训,成都大数据培训,成都会计实操培训,成都IT培训,成都编程培训等IT培训,专业的成都软件培训机构,专业师资授课,真实项目实战、零首付、低押金、名企就业