Unity string performance issues

Preface

Share some knowledge learned through books and the Internet.
Every time you dynamically create a string, C# will allocate a memory in the heap memory to allocate the string. Because C# does not have a caching mechanism for strings, it will cause every connection, cutting, and combination. New memory will be applied for every time, and the original memory will be abandoned, waiting for GC, and GC will consume a lot of CPU space. For example, for a = "ax"; c = "b" + a + "c", it will cause a certain degree of A waste of performance. Because the + operator here is performed at runtime, not at compile time. Therefore, each + operation creates a new string object instead of changing the original object. This will produce two useless intermediate objects, "bax" and "baxc", which occupy memory space. If you are not careful, it will gradually increase the program lag and reduce operating efficiency. There are several ways to improve string efficiency. Please pay attention. StringFormat, using + splicing and $ syntactic sugar will have certain efficiency problems. To improve efficiency, try to use StringBuilder. However, for readability, if the string is short and low-frequency, syntax sugar is enough.

id - string dictionary pool

Build a Key-string cache pool yourself. When fighting, look for
Dict<int,string> from the pool to reduce GC.

Dictionary<int,string> strCache;
string strName = null;
if(!strCache.TryGetValue(id, out strName))
{
ResData resData = GetDataById(ID);
string strName = "This is " + resData,Name;
strCache.Add(id,strName);
}
return strName;

Make a fixed-length string pool and use pointers to splice strings

Point the pointer to the target string, and put strA and strB in the front and back positions respectively to reduce the number of memory allocations and releases.

public unsafe string Concat(string strA, string strB)  
{  
    int a_length = strA.Length;  
    int b_length = strB.Length;  
    int sum_length = a_length + b_length;  
    string strResult = null;  
    if (!cacheStr.TryGetValue(sum_length, out strResult))  
    // 如果不存在 sum_length 长度的缓存字符串,那么直接连接后存入缓存  
    {  
        strResult = strA + strB;        cacheStr.Add(sum_length, strResult);  
        return strResult;  
    }    //字符串再利用  
    fixed (char* strA_ptr = strA)  
    {        fixed (char* strB_ptr = strB)  
        {            fixed (char* strResult_ptr = strResult)  
            {                memcopy((byte*)strResult_ptr, (byte*)strA_ptr, a_length * sizeof(char));  
                memcopy((byte*)strResult_ptr+a_length,(byte*)strB_ptr,b_length * sizeof(char));  
            }        }    }    return strResult;  
}

memcopy function

public unsafe void memcopy(byte* dest, byte* src, int len)  
{  
    while((--len)>=0)  
    {dest[len] = src[len];}}

StringBuilder

It can also solve the GC problem when creating strings multiple times and splicing them repeatedly. StringBuilder is variable, which means it can modify the original string without creating a new string object, which can save memory space. and improve efficiency. StringBuilder supports chain calls, which can easily perform multiple string operations, such as builder.Append("a").Append("b").Append("c"). StringBuilder can dynamically adjust its capacity. When the string length exceeds the current capacity, it will automatically expand the capacity without throwing an exception.
The disadvantage is that stringBuilder is thread-unsafe, which means that in a multi-threaded environment, if multiple threads modify the same StringBuilder object at the same time, data inconsistency or errors may result. The ToString method of StringBuilder needs to traverse its internal character array and splice it into a new string object. This process may consume a certain amount of time and resources. StringBuilder will only create a string once during toString, which greatly reduces the pressure on CPU performance compared to the previous creation of strings multiple times.

Guess you like

Origin blog.csdn.net/TongOuO/article/details/132522681