通常情况下,我们都使用Unity中的Debug类来输出log信息,但是log的输出会产生内存分配,同时对性能也会产生影响。来看下面的代码:
Profiler.BeginSample(">>>>>Log Test");
for (int i = 0; i < 100; ++i)
Debug.Log("Call: " + i);
Profiler.EndSample();
在真机上运行,会产生将近4MB的内存分配,并且CPU耗时达到了495ms:
频繁的内存分配会加速GC的到来,从而进一步对性能产生负面影响。因此,在发布项目时,我们都会选择关闭log输出,Unity在Player Settings中提供了该功能:
但是,该功能的作用仅仅在于Unity内部不再输出log,传递的参数产生的内存分配和CPU耗时仍然是无法避免的。仍然以上面的代码为例,在Debug.Log的调用中,我们传递的参数为"Call: " + i,很明显这需要将整型i装箱,从而会产生内存分配。我们关闭log输出后再次在真机上运行,结果如下:
可以发现仍然无法避免参数引起的内存分配和耗时。那么该如何解决这个问题呢?最好的方式就是在编译时去除函数的调用,这就是C#的Conditional属性的作用。
我们对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宏的情况下上真机测试:
此时就不会有内存分配和CPU耗时了
本文固定链接: http://www.jianshu.com/p/814b4b322623
转载请注明: EnigmaJJ 2017年09月07日 于 简书 发表
网友评论