优秀博客分享

平时看到的一些比较有意思的博客,或者干货

Posted by yebin-yu on August 31, 2023
2023-03-31 还在无脑用 StringBuilder?来重温一下字符串拼接吧
讲了实现 “A” + “B” + “C” 底层逻辑,根据Java的版本来分析最优策略。

# Java9之前
字符串拼接是用StringBuilder实现的,会new一个StringBuilder来拼接字符串,然后通过toString返回。第一个弊端是会创建多余的对象,第二个弊端是append的时候StringBuilder会不断扩容,多次内存分配导致性能变差。

# Java9
#### Indify String Concatenation
改成了JVM 会生成对应的负责拼接字符串的函数,函数内部可以进行各种优化。
JVM 在执行到 InvokeDynamic 指令时会自动使用 makeConcatWithConstants 优化,生成一个对应的 CallSite 对象,用优化过的 CallSite 对象对字符串进行拼接。此后此处所有的字符串拼接都会使用同一个 CallSite 对象。

优点:
1. int等基础类型的值不会被Boxing之后再Unboxing,而是用动态生成的函数直接拼接。
2. 具体实现不清楚,但可能是创建StringBuilder的基础上,增加了大小,也就是 new StringBuilder(a.size() + ...),速度和内存消耗都有提升


#### 字符串压缩
ASCII只要用1byte,如果全是ASCII,则能节省一半的空间。

缺点:
1. StringBuilder还是默认会对字符串的byte做压缩,中文无法压缩,所以中文的话每次都要分配两次内存,至今(Java19),StringBuilder都没有对此做优化。

# Java 15
削减了一些 Indify String Concatenation 的一些性能不佳的策略。
实现大概为:`需要一次复制的策略:我们先准确分配好 a + b + c 所需的空间,把 a, b, c 的内容复制到我们分配的空间里, 最后直接把我们分配的空间通过内部 API 传给字符串。`