Unity优化——字符串篇

处理字符串和文本是Unity项目中性能问题的常见来源。在C#中,所有的字符串都是不可变的。对字符串的任何操作都将导致分配一个完整的新字符串。

当连接N个字符串的时候,会有N-1中间字符串分配,依次连接也会给内存管理带来压力。对于需要进行连接的字符串,推荐用StringBuild去减伤内存分配。一个StringBuild的实例可以重复使用,进一步减少内存分配。

重复字符串

在查看Mono内存的时候发现字符串是内存的使用大头,发现里面会存在很多重复的字符串。这些字符串都是运行时创建的,因为没有消除重复导致占用大量内存。

当读取一个N行的文件,每行的内容都是一样的时候,这个字符串会再内存中创建N份。推荐用String.Intern & String.IsInterned来管理字符串。对所有创建出来的常驻String做一次String.Intern操作,则可以使所有字符串唯一。对非常驻的String,我们可以自己创建一个StringPool来维护唯一字符串,在合适的时机释放这个Pool清理内存。

字符串比较

在字符串相关代码中经常发现的核心性能问题之一是使用默认的慢速API。这些API接口的默认行为是能处理不同文化与语言规则的字符串。

    string separated = "\u0061\u030a";
    string combined = "\u00e5";
    Console.WriteLine(String.Compare(separated, combined) == 0);
    // result is True
    Console.WriteLine(String.Compare(separated, combined, StringComparison.Ordinal) == 0);
    // result is False

复杂的规则必然带来的是执行的不高效,而且这功能在大部分的Unity工程里面是不需要的。

低效的字符串API

写了一个简单的脚步测试字符串API的速度

    StringBuilder sBuilder = new StringBuilder();
    System.Random random = new System.Random();
    for (int i = 0; i < 100; ++i)
    {
       sBuilder.Append((char)(random.Next() % 256));
    }
    string str = sBuilder.ToString();
    string preStr = str.Substring(0, 16);
    string lastStr = str.Substring(str.Length - 16, 16);
    int cnt = 0;
    for (int i = 0; i < 100 * 1024; ++i)
    {
        if (str.StartsWith(preStr)) ++cnt;
        if (str.StartsWith(lastStr)) ++cnt;
    }

测试结果

MethodTime(ms) 100k compares
String.StartsWith,default culture360ms
String.EndsWith,default culture12465ms
String.StartsWith,Ordinal357ms
String.EndsWith,Ordinal174ms
CustomStartsWith18ms
CustomEndsWith17ms

字符串比较接口默认行为

Func NameDefault interpretation
String.CompareStringComparison.CurrentCulture
String.CompareToStringComparison.CurrentCulture
String.EqualsStringComparison.Ordinal
String.ToUpperStringComparison.CurrentCulture
Char.ToUpperStringComparison.CurrentCulture
String.StartsWithStringComparison.CurrentCulture
String.IndexOfStringComparison.CurrentCulture
    原文作者:carber
    原文地址: https://www.jianshu.com/p/3b5de9734ed1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞