StringBuilder建议已死?


使用StringBuilder而不是String实现字符串连接已经只是一个古老的神话。

在大多数情况下,它不再正确的。

你可以在代码中安全地使用String 1 + String 2,并且不会注意到任何差异。

曾几何时,需要使用StringBuilder进行手动的字符串构造,但现代的Java已经不需要这样了。当然,StringBuilder并没有死,但总是使用它的直白建议只是适得其反。

这个建议源于Java字符串的一般属性是不可变的。因此,即使在中间操作中也会创建临时的字符串。一个StringBuilder避免了临时的中间字符串。

顺便说一句,这个神话有一个兄弟:"总是使用一个适当大小的StringBuilder"。让我们讨论一下这些神话,在讨论的同时,你会看到运行微观基准测试的一步步方法。从小处着手,成长,观察。

原理
现代Java(即JDK 11或更高版本)不再需要使用StringBuilder进行字符串连接,因为JVM自己会更有效地进行连接。

这不会需要更多的内存或导致速度下降。只有一些特殊的操作,比如在循环中重复串联,可能仍然需要使用旧的StringBuilder方法。

我们还将在此提出一个理论,即冷代码(如只启动的代码)可能会从旧的编程模式中受益,因为JVM还没有能力编译合适代码。

具体测试点击标题

结论
对于99.5%的人来说,如果你写的是不经常被调用的普通Java代码,请不要听从StringBuilder的建议,因为你会在内存消耗(大小)和主要是运行时间方面犯错。

当你不能以str1+str2等流利的方式编写代码时,你也会立即失去易读性。此外,你的代码看起来会很糟糕,而且会更难理解。

此外,如果你真的想获得3-6纳秒的运行时间差异,你不能只是把一个换成另一个。相信我,字符串代码很可能不是你的问题。当然,当你运行你自己的日志库,或者你在LOG4J上面放了一层丰富的数据,是的,你可能会用StringBuilder赢得一点,但你必须仔细衡量。不要暗示什么!

最重要的收获是减少内存的搅动,而不是减少运行时间。

只有两个真正合法的理由使用StringBuilder:

  • 你是在真正的构建一个字符串,因此你可能会运行一个循环或类似的未定义数量的组件
  • 你的代码是冷的,只会被执行几次,所以它没有机会预热,而且这段代码会在你的应用程序的运行时间中留下明显的痕迹

另外,正如我们所看到的,我们有许多边缘案例,在这些案例中,严重优化的虚拟机击败了简单代码的地狱。任何更复杂的东西都是更慢的。