Unity中的Log优化

本文转自大神同事EnigmaJJ简书:http://www.jianshu.com/p/814b4b322623,有个人轻微修改,请点击链接查看原文,尊重楼主版权。


Unity中的Log


通常情况下,我们都使用Unity中的Debug类来输出log信息,但是log的输出会产生内存分配,同时对性能也会产生影响。

来看下面的代码:

Profiler.BeginSample(">>>>>Log Test");
for (int i = 0; i < 100; ++i)
    Debug.Log("Call: " + i);
Profiler.EndSample();
在真机上运行,会产生将近4MB的内存分配,并且CPU耗时达到了495ms:

Unity中的Log优化_第1张图片

频繁的内存分配会加速GC的到来,从而进一步对性能产生负面影响。

因此,在发布项目时,我们都会选择关闭log输出,Unity在Player Settings中提供了该功能:

Unity中的Log优化_第2张图片

但是,该功能的作用仅仅在于Unity内部不再输出log,传递的参数产生的内存分配和CPU耗时仍然是无法避免的。

仍然以上面的代码为例,在Debug.Log的调用中,我们传递的参数为"Call: " + i,很明显这需要将整型i装箱,从而会产生内存分配。我们关闭log输出后再次在真机上运行,结果如下:

可以发现仍然无法避免参数引起的内存分配和耗时。

那么该如何解决这个问题呢?最好的方式就是在编译时去除函数的调用,这就是C#的Conditional属性的作用。(C#特性可参考: C#特性(Attribute))
我们对log输出封装一层:

[System.Diagnostics.Conditional("LOG")]
public void LogWrap(string str)
{
    Debug.Log(str);
}
接着把函数调用改为封装的函数:

Profiler.BeginSample(">>>>>Log Test");
for (int i = 0; i < 100; ++i)
    LogWrap("Call: " + i);
Profiler.EndSample();
在不定义LOG宏(且当前脚本没有条件编译#define LOG)的情况下上真机测试:



此时就不会有内存分配和CPU耗时了,贊!

还有一个需要注意的地方,开发中打log总会需要使用格式,这里我们可以在LogWrap中转换格式,若在外部转格式,则关闭log的情况下还是会有无意义的转格式的开销。

------------------------------------------------------------------------------------------------------

条件编译可参考:http://blog.csdn.net/qq_33337811/article/details/77888154

本文固定链接: http://www.jianshu.com/p/814b4b322623
转载请注明: EnigmaJJ 2017年09月07日 于 简书 发表。

你可能感兴趣的:(游戏优化)