unity中0GC优化方案《zstring》

文章目录

  • 序言
  • 简介
  • GC带来的问题
    • 性能瓶颈
    • 玩家体验受损
  • 使用方式

序言

游戏开发秉承遇到好东西要分享,下面介绍zstring,感谢作者开源无私奉献
源码地址:https://github.com/871041532/zstring

简介

GC带来的问题

性能瓶颈

GC暂停主线程执行:当.NET的垃圾回收器开始工作时,它会暂时挂起所有程序执行以进行内存清理和整理。这意味着游戏逻辑、物理计算、渲染等都会被迫暂停,这会导致帧率下降或卡顿,影响游戏流畅度。
帧时间不一致:
由于GC的发生不可预知,其带来的延迟可能导致每一帧的时间长度不稳定,这对于实时交互的游戏体验尤其不利,特别是在需要保持稳定刷新率(如60fps)的场景。

玩家体验受损

突然的卡顿会影响玩家沉浸感,并可能导致在关键的游戏时刻出现响应延迟,比如战斗中的操作反馈或者复杂场景加载时的视觉表现。
资源浪费:
频繁的内存分配与回收也会增加系统的内存管理开销,导致整体系统效率降低,可能消耗更多的CPU周期和其他系统资源。
潜在的内存泄漏:
如果因为编程习惯不良而导致大量短生命周期对象不断产生并触发GC,则可能存在未被正确释放的内存,久而久之可能会引发内存泄漏,使得可用内存逐渐减少,最终导致游戏崩溃或其他严重问题。
因此,在Unity开发中,开发者需要密切关注代码设计,采用合适的数据结构、内存管理和对象池技术来最小化临时对象的创建和销毁,从而最大限度地减少对GC的依赖。

在Unity中实现0GC(零垃圾回收)的目标,主要是为了避免频繁触发.NET的垃圾回收机制,因为垃圾回收会导致短暂的帧率下降和性能波动。
C# 0GC字符串补充方案。结合gstring与CString两者特点(向这两个方案的作者致敬),只有一个文件,性能与使用方便性高于两者。

报告地址:
https://coh5.cn/p/1ace6338.html

使用方式

1.Unity引擎将zstring.cs文件放于plugins目录下即可使用(不在plugins目录,则IOS打包或IL2CPP打包等FULLAOT方式编译不过),或者直接把结构体定义放入zstring类中;其余C#程序将zstring.cs直接放入工程使用即可。

2.(最佳性能)当update每帧刷新标签显示,或者大量UI飘字,或者该字符串是短时间使用的则使用如下方式:

   using (zstring.Block())
    {
        uiText1.text=(zstring)"hello world"+" you";
        uiText2.text=zstring.format("{0},{1}","hello","world");
    }

此方式设置的string值位于浅拷贝缓存中,一定时间可能会改变,出作用域后正确性不予保证。

3.资源路径这种需要常驻的则需要intern一下在作用域外使用

     using (zstring.Block())
    {
        zstring a="Assets/";
        zstring b=a+"prefabs/"+"/solider.prefab";
        prefabPath1=b.Intern();

        prefabPath2=zstring.format("{0},{1}","hello","world").Intern();
    }

此方式设置的string值位于深拷贝缓存中,游戏运行期间不会改变,可以在作用域外使用。

4.不可使用zstring作为类的成员变量,不建议在using作用域中写for循环,而是在for循环内using。

5.首次调用时会初始化类,分配各种空间,建议游戏启动时调用一次using(zstring.Block()){}

6.0GC。时间消耗上,短字符串处理,zstring比gstring时间少20%30%,比原生慢。大字符串处理,zstring比gstring时间少70%80%,接近原生string速度。

7.追求极限性能的话,核心函数可以用C++Dll中的 memcpy内存拷贝函数,性能提升10%~20%,一般没这个必要。

8.测试打开zstringTest工程,在Test脚本上勾选与不勾选bigStringTest下查看Profile性能。(同时对比了zstring,gstring,CString,还有王国纪元里的string)

9.据热心用户反应,IL2CPP 2017.4 在 Android上有字节对齐问题,换成2018就木有了。所以此时解决办法有三个:1.IL2CPP换成2018以上版本。 2.719行左右的memcpy函数换成循环一次拷贝一个字节。 3.不怕麻烦的话此处调用C语言的内存拷贝函数dll,即C语言中的memcpy,这样性能也更高。
当前Untiy版本有函数UnsafeUtility.MemCpy直接拷贝内存,建议用这个函数替换memcpy函数。

python学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

你可能感兴趣的:(unity,游戏引擎,c#)