gc方法写法_Unity3D研究院之字符串拼接0GC(一百零四)

本文探讨了在Unity3D中优化字符串拼接以减少垃圾收集(GC)的方法。主要关注点包括避免装箱操作、减少使用`string.Format`、重用`StringBuilder`以及使用无装箱版本的算法。通过代码示例展示了不同字符串拼接方式对GC的影响,并提供了减少内存开销的实践技巧。
摘要由CSDN通过智能技术生成

最近在优化项目,发现字符串拼接的堆内存非常大,而且非常频繁。

大概原因如下

1.字符串就是char[] 长短发生变化必然要重新分配长度,以及拷贝之前的部分,产生GC

2.字符串+=进行拼接会产生装箱,生成GC

3.Append传入值类型数据,它会调用ToString方法,需要new string 然后把char[]拷进去,又会产生堆内存。

4.new StringBuidler 产生堆内存

5.StringBuidler.ToString 产生堆内存

5.string.format 它内部使用的就是StringBuilder,但是 1)new StringBuilder 2)Append 3)ToString都会产生堆内存。

所以我们需要优化的是

1.

int a = 100;

string b = a + “”;

禁止上述这种写法,会额外产生一次装箱操作。所以要采用如下写法。

string b = a.ToString();

2.少用或者不用string.format,提前缓存共享StringBuilder对象。避免用时候产生堆内存。

3.网上找到一个算法,挺有意思。提前定义好 0 – 9 之间的字符数组,如果传入值类型数据,从高位依次除以10算出每一位的数,然后再去预先声明的0-9字符数组中找对应的char,这样就就不会产生装箱GC了。

4.如果可以提前确定字符串的长度,例如,界面上显示玩家的等级, 我们可以确定level不可能超过3位数也就是100,那么可以提前声明一个长度为3的StringBuilder,通过反射取出来内部的_str,这样就可以避免最后的ToString产生的堆内存了。由于_str内容可能无法擦掉之前的所以需要调用GarbageFreeClear();方法。

1.装箱版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

usingSystem.Text;

usingUnityEngine;

usingUnityEngine.Profiling;

publicclassNewBehaviourScript:MonoBehaviour{

StringBuilderm_StringBuilder=newStringBuilder(100);

stringm_StringBuildertxt=string.Empty;

privatevoidStart()

{

m_StringBuildertxt=m_StringBuilder.GetGarbageFreeString();

}

privatevoidUpdate()

{

inti=Random.Range(0,100);

floatf=Random.Range(0.01f,200.01f);

floatd=Random.Range(0.01f,200.01f);

strings="yusong: "+i;

Profiler.BeginSample("string.format");

strings1=string.Format("{0}{1}{2}{3}",i,f,d,s);

Profiler.EndSample();

Profiler.BeginSample("+=");

strings2=i+""+f+""+d+""+s;

Profiler.EndSample();

Profiler.BeginSample("StringBuilder");

strings3=newStringBuilder().Append(i).Append(f).Append(d).Append(s).ToString();

Profiler.EndSample();

Profiler.BeginSample("StrExt.Format");

strings4=StrExt.Format("{0}{1:0.00}{2:0.00}{3}",i,f,d,s);

Profiler.EndSample();

Profiler.BeginSample("EmptyGC");

m_StringBuilder.GarbageFreeClear();

m_StringBuilder.ConcatFormat("{0}{1:0.00}{2:0.00}{3}",i,f,d,s);

strings5=m_StringBuildertxt;

Profiler.EndSample();

Debug.LogFormat("s1 : {0}",s1);

Debug.LogFormat("s2 : {0}",s2);

Debug.LogFormat("s3 : {0}",s3);

Debug.LogFormat("s4 : {0}",s4);

Debug.LogFormat("s5 : {0}",s5);

}

}

2.无装箱版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

usingSystem.Text;

usingUnityEngine;

usingUnityEngine.Profiling;

publicclassNewBehaviourScript:MonoBehaviour{

StringBuilderm_StringBuilder=newStringBuilder(100);

stringm_StringBuildertxt=string.Empty;

privatevoidStart()

{

m_StringBuildertxt=m_StringBuilder.GetGarbageFreeString();

}

privatevoidUpdate()

{

inti=Random.Range(0,100);

floatf=Random.Range(0.01f,200.01f);

floatd=Random.Range(0.01f,200.01f);

strings="yusong: "+i.ToString();

Profiler.BeginSample("string.format");

strings1=string.Format("{0}{1}{2}{3}",i.ToString(),f.ToString(),d.ToString(),s);

Profiler.EndSample();

Profiler.BeginSample("+=");

strings2=i.ToString()+f.ToString()+d.ToString()+s;

Profiler.EndSample();

Profiler.BeginSample("StringBuilder");

strings3=newStringBuilder().Append(i).Append(f).Append(d).Append(s).ToString();

Profiler.EndSample();

Profiler.BeginSample("StrExt.Format");

strings4=StrExt.Format("{0}{1:0.00}{2:0.00}{3}",i,f,d,s);

Profiler.EndSample();

Prof

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值