千家信息网

Unity中如何优化字符串和文本

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要介绍Unity中如何优化字符串和文本,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!字符串和文本:在Unity项目中,处理字符串和文本经常会产生性能问题。在C#中,字
千家信息网最后更新 2025年01月23日Unity中如何优化字符串和文本

这篇文章主要介绍Unity中如何优化字符串和文本,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

字符串和文本:

在Unity项目中,处理字符串和文本经常会产生性能问题。在C#中,字符串是不变的。任何对字符串的操作都会重新分配新的字符串,这个代价是非常昂贵的。如果在多重循环中重复地执行字符串连接操作,就会造成性能问题,特别是对长的字符串或者大的数据集操作的时候。

因此,把N个字符串连接起来就会分配N-1个中间的字符串,这样连续的操作就会对堆内存产生压力。

当我们需要在多重循环中或者每一帧对字符串进行操作时,记得使用StringBuilder来操作字符串。StringBuilder也还能被重用,以进一步减少内存的分配。

关于字符串的使用,详细内容也可以参考微软发布的文档:

Best Practices for Using Strings in .NET docs.microsoft.com

https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings

地域限制和顺序比较:

与字符串相关代码的一个核心问题就是无意中会使用默认的、慢的字符串API。这些API的目的是为了一些商业化的应用,能够处理出现在文本中的有关不同文化和语法规则的字符。

比如,下面的代码在一些使用美式英语的地区运行时,会返回true。在欧洲地区运行时,返回false。

提示:Unity脚本都是基于美式英语来运行的。

对于大多数的项目,这个完全没有必要。而且我们简单对每个字符进行比较,判断两个字符串是否相等,这速度大约会比使用上面的方式快10倍。当然,我们也可以调用String.Equals方法,然后设置比较类型StringComparison.Ordinal来实现:

低效率的内置字符串API:

除了上面讲的顺序比较外,也有一些C#的字符串的API效率比较低。比如:String.Format,String.StartsWith和String.EndsWith。以下是Unity给出的一些测试数据:

可见,如果是我们自己实现String.StartsWith和String.EndsWith,执行效率会高的多。实现方法也可以参考下图:

正则表达式:

在字符串匹配和操作字符串方面,正则表达式是非常消耗性能的。而且,C#类库也实现了正则表达式。所以,即使是调用IsMatch这样简单的函数,都会临时分配很多的内存。我们在开发中,出了初始化会临时分配内存外,应该不允许在其他地方临时分配较多内存。

如果一定要用正则表达式的话,注意不要使用静态的Regex.Match和Regex.Replace方法。这两个方法会动态的编译正则表达式,但不会缓存生成的对象。

下面是使用正则表达式的一个例子:

每一次以上的代码被执行,它都会生成5kb的内存垃圾。为了减少垃圾的生成,我们需要对以上代码进行重构:

在这个例子中,每一次调用myRegExp.Match只会产生320b的内存垃圾。对于简单的字符串匹配而言,它对内存的消耗依旧有点多,但与之前的例子相比,这已经是很大的改进了。

因此,如果正则表达式是不变的字符串常量,那么把它们当作第一个参数传递给Regex的构造器来预编译它们会更加有效。这些Regex对象也是可以被重用的。

XML, JSON和其他的长篇文本解析:

在loading时,解析文本通常是一项耗时的操作。有些情况下,解析文本所花的时间会超过loading和实例化Assets的时间。

这原因取决于我们用的文本解析器。C#内置的XML解析器是非常灵活的,但是,它不能对一些特殊的数据布局进行优化。

许多第三方解析器都是基于反射构建的。虽然在开发中使用反射是一个不错的选择(因为它能很好的适应数据布局的变化),但用反射是非常慢的。

Unity已经引入了一个带有内置JSONUtility API(可参考:https://docs.unity3d.com/ScriptReference/JsonUtility.html)的局部解决方案,它为Unity的序列化系统提供了一个接口,用来处理JSON数据。在许多方面它是优于C#的JSON解析器。但是它也有不足之处,在不添加额外代码的情况下,它不能序列化许多复杂的数据类型,比如字典(在Unity的序列化过程中,请参阅ISerializationCallbackReceiver接口,以方便转换一些复杂的数据类型)

如果在文本解析中遇到性能问题,可以考虑以下的解决方案:

1.在Build时进行解析

当我们需要解析文本时,最好避免在游戏中进行这一步的操作。我们可以在Build的时候把文本解析成二进制文件。以加快读取时的速度。

2.数据分割和延迟加载

第二种情况情况是我们需要把能解析成小块的数据分割开来。一旦分割,数据解析就可以在不同时间进行。在理想的情况下,我们确定哪部分数据是会用到的,然后只加载用到的那部分数据。

3.线程

对于那些不需要用Unity API来操作的数据,可以在另外的线程中来解析它们。这可以提高多核CPU的利用率,是相当有用的。当然,我们在写代码时需要注意避免死锁。

以上是"Unity中如何优化字符串和文本"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

字符 字符串 数据 文本 内存 正则 表达式 代码 分配 情况 C# 性能 方法 问题 参考 例子 内容 垃圾 序列 时间 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百度为什么会出现未连接服务器 帝国神话服务器人数才100 搞软件开发的人才叫 所有电脑都能用于软件开发吗 给代理服务器添加nagle算法 数据库的图片字段类型 网络安全管理指导思想 华为手机塔式服务器能插多少盘 没有服务器怎么进行小程序开发 数据库为什么无法保存选定项 中国民营软件开发公司排名 cs手机版僵尸服务器 数据库的创建与操作实验总结 远程服务器打不开软件怎么解决 轮回服几个服务器的任务 数据库重密码 中国网络安全行业人才 服务器插了移动硬盘没反应 维护网络安全发声亮剑 三星研究所软件开发 学位论文数据库标注方式 直销软件开发定制 拉丁互联网科技有限公司 软件开发工作干什么的 什么属于网络安全被动攻击 成都商城软件开发哪里好 sdk和软件开发的区别 三季度网络安全形势严峻 软件开发费用税前列支 数据库报表怎样填表格框线
0