05. Java的StringBuffer
大约 2 分钟
在本文章中,我们将学习Java中StringBuilder和StringBuffer之间的异同。
StringBuilder是在Java 1.5中引入的,作为StringBuffer的替代品。
StringBuilder和StringBuffer异同
StringBuilder 和 StringBuffer 都创建包含可变字符序列的对象。
让我们看看它是如何工作的,以及它与不可变字符串类 String 的比较:
String immutable = "abc";
immutable = immutable + "def";
尽管看起来我们通过连接符连接 def 来修改同一对象,但其实正在创建一个新对象,因为 String 实例无法修改。
而使用 StringBuffer 或 StringBuilder 时,我们可以使用 append() 方法:
StringBuffer sb = new StringBuffer("abc");
sb.append("def");
这里没有创建新对象。我们在 sb 实例上调用了 append() 方法,并修改了其内容。StringBuffer 和 StringBuilder 是可变对象。
不同之处:
StringBuffer:使用了
synchronized关键字,因此线程安全。StringBuilder:线程不安全,速度更快,API方法与
StringBuffer一致。
基准测试
在迭代次数小时,两者性能的差异微乎其微,我们可以用 JMH 做一个微基准测试,反应出性能速度的差别:
@State(Scope.Benchmark)
public static class MyState {
int iterations = 1000;
String initial = "abc";
String suffix = "def";
}
@Benchmark
public StringBuffer benchmarkStringBuffer(MyState state) {
StringBuffer stringBuffer = new StringBuffer(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuffer.append(state.suffix);
}
return stringBuffer;
}
@Benchmark
public StringBuilder benchmarkStringBuilder(MyState state) {
StringBuilder stringBuilder = new StringBuilder(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuilder.append(state.suffix);
}
return stringBuilder;
}
我们使用了默认的吞吐量模式——即每单位时间的操作(得分越高越好),上述测试有如下结果:
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops/s
当迭代次数从 1K 调整为 1M 时,更能看清楚这种差别:
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops/s