StringBuilder性能远超+拼接,因前者复用缓冲区避免频繁对象创建,后者每次拼接都生成新String;JMH测试显示前者快约70倍,VB.NET中差距更达700倍。

如果您在Java或C#等语言中进行大量字符串拼接操作,发现程序响应变慢或内存占用异常升高,则很可能是由于使用了低效的拼接方式。以下是针对StringBuilder与点号(+)拼接方式的性能实测对比及优化路径:
一、理解两种拼接机制的本质差异
点号(+)拼接在编译期会被转换为StringBuilder.append()调用,但每次拼接完成后都会立即调用toString()生成新String对象,导致频繁创建不可变对象并触发数组拷贝;而StringBuilder是可变字符缓冲区,仅在最终调用toString()时才生成一次String实例,避免中间冗余对象开销。
1、String s = "a" + "b" + "c"; 编译后等价于 new StringBuilder().append("a").append("b").append("c").toString();
2、若该表达式位于循环内,如 for (int i=0; i
3、StringBuilder sb = new StringBuilder(); sb.append("a").append("b").append("c"); 仅维护同一内部char[],扩容仅发生数次,无中间String对象产生。
二、JMH基准测试数据呈现
采用Java Microbenchmark Harness(JMH)对10万次拼接执行5轮预热+10轮测量,结果如下:
1、String "+" 拼接:平均耗时 830,811 ns/op
2、StringBuilder append():平均耗时 12,032 ns/op
3、二者性能比约为 69:1,即StringBuilder快近70倍。
三、规避隐式StringBuilder重建的编码实践
即使使用+拼接,若出现在循环体或方法多次调用路径中,编译器无法跨迭代优化,仍将生成多个临时StringBuilder实例。需主动将拼接逻辑移出高频执行路径,并复用同一StringBuilder实例。
1、错误写法:for (int i = 0; i
2、正确写法:StringBuilder sb = new StringBuilder(); for (int i = 0; i
3、关键提示:若已知最终字符串长度范围,应预先设置容量,如 new StringBuilder(estimatedLength),避免多次数组扩容拷贝。
四、VB.NET环境下的等效验证
在VB.NET中,& 运算符行为与Java中+类似,底层依赖String.Concat或临时StringBuilder;而直接使用System.Text.StringBuilder类可获得同等性能优势。
1、Dim s As String = "" : For i = 1 To 100000 : s &= i.ToString() : Next —— 实测耗时约 2140 ms
2、Dim sb As New StringBuilder() : For i = 1 To 100000 : sb.Append(i.ToString()) : Next : Dim s As String = sb.ToString() —— 实测耗时约 3 ms
3、二者差距达700倍以上,印证了可变缓冲区对高频拼接的关键价值。
五、String.format与StringBuilder的适用边界
String.format适用于格式化模板固定、参数较少且非循环场景,其内部仍使用StringBuilder构建,但增加了格式解析开销;在纯拼接任务中,直接调用append()链式调用更轻量。
1、URL参数拼接示例:url + "?a=" + a + "&b=" + b —— 编译后生成多个StringBuilder实例
2、等效StringBuilder写法:new StringBuilder(url).append("?a=").append(a).append("&b=").append(b).toString() —— 单实例、零中间String
3、重要提醒:当拼接项含null时,StringBuilder.append(null)会写入字符序列"null",而+拼接同样如此,行为一致,无需额外判空处理。


















