Unity C#值类型与字符串连接实测

2020-09-16  本文已影响0人  雄关漫道从头越

最近学习了下IL,寻思着小试牛刀,学以致用嘛。
所以就拿值类型与字符串连接来作了几组测试,使用Unity的Profiler提供的BeginSample和EndSample查看GC和cpu耗时,先把结果展示出来。

一、字符串连接代码与Profile展示

1.直接使用"+"连接一次,值类型不调用ToString方法
"+"连接一次无ToString
"+"连接一次无ToString的Profile
"+"连接无ToString发生装箱
2.直接使用"+"连接一次,值类型调用ToString方法
"+"一次有ToString
"+"一次有ToString的Profile
"+"一次有ToString无装箱
3.使用String.Format连接一次,值类型不调用ToString方法
String.Format一次无ToString
String.Format一次无ToString的Profile
4.使用String.Format连接一次,值类型调用ToString方法
String.Format一次有ToString
String.Format一次有ToString的Profile
5.使用StringBuilder连接一次(StringBuilder重载支持基本的值数据类型)
StringBuilder一次 一次StringBuilder的Profile

可以看出无论是使用"+"号连接还是使用String.Format方法,Time.time(值类型)没有调用ToString方法的,GC多出20B,cpu耗时都在0.01ms,无明显差别,StringBuilder因为重载了Append方法,可以看出与值类型的ToString后连接的方式GC一致。
接下来我们循环100次,再看看结果。

6.直接使用"+"连接100次,值类型不调用ToString方法
"+"连接100次无ToString
"+"连接100次无ToString的Profile
7.直接使用"+"连接100次,值类型调用ToString方法
"+"连接100次有ToString
"+"连接100次有ToString的Profile
8.使用String.Format连接100次,值类型不调用ToString方法
String.Format连接100次无ToString
String.Format连接100次无ToString的Profile
9.使用String.Format连接100次,值类型调用ToString方法
String.Format连接100次有ToString
String.Format连接100次有的Profile
10.使用StringBuilder连接100次(StringBuilder重载支持基本的值数据类型)
StringBuilder100次 StringBuilder100次的Profile

循环100次与单独一次GC几乎是没有差异的,约等于乘以100,而在耗时上"+"连接与StringBuilder是一致,似乎比String.Format耗时更短,因耗时在百分之一毫秒级,这里不做深究,但是可以看出值类型与字符串连接时,值类型的ToString方法调用与否会影响GC的开销。

二、IL代码分析

我们再来看一下IL代码。

"+"连接无ToString发生装箱
"+"连接有ToString无装箱
String.Format无ToString发生装箱
String.Format有ToString无装箱
StringBuilder无装箱

通过IL代码我们可以确定,额外的GC开销是因为值类型与字符串连接时,因为未调用ToString方法,会发生一次装箱操作,我们来看看String.Format方法的参数


String.Format方法

参数是作为object传入,所以会先从值类型转换到object类型,将值从堆栈中copy到托管堆,新建一个object类型的数据,再执行字符串连接操作,而值类型调用ToString方法后,直接就可以执行字符串连接操作。

三、测试结果图表展示

测试结果比较
GC结果比较
耗时结果比较

四、结论

1.值类型在与字符串连接时,无论是"+"连接,还是String.Format方法当值类型没有调用ToString方法时,都会发生装箱操作,带来额外的GC开销(cpu耗时开销不明显)
2.为了避免不必要的开销,值类型在与字符串连接时,值类型应该先调用一下ToString方法,养成好习惯。

最后,我也看到有些文章提到其实没有必要手动ToString,首先消耗并不多,而且也影响代码的美观,不过我觉得性能应该是第一位,没有好的性能,再美观的代码,用户也不会认可,用户不会去关心代码优不优雅,美不美观,用户只关心app是不是耗电,是不是卡顿。

上一篇 下一篇

猜你喜欢

热点阅读