关于StringBuilder中设置初始容量对性能的测试
Contents
被测试代码
package org.agoncal.sample.jmh;
/**
* Created by emacsist on 2017/6/16.
*/
public class StringAppend {
public static String defaultBuilder(int len) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
sb.append(i);
}
return sb.toString();
}
public static String bufferBuilder(int len) {
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
sb.append(i);
}
return sb.toString();
}
}
基准测试代码
package org.agoncal.sample.jmh;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
* Created by emacsist on 2017/6/9.
*/
@BenchmarkMode(Mode.All)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
public class Main {
@Benchmark
public void benchmark(){
StringAppend.defaultBuilder(10000);
}
@Benchmark
public void benchmarkFinal(){
StringAppend.bufferBuilder(10000);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(Main.class.getSimpleName())
.forks(1)
.measurementIterations(10)
.warmupIterations(20)
.build();
new Runner(opt).run();
}
}
测试结果
# Run complete. Total time: 00:40:59
Benchmark Mode Cnt Score Error Units
Main.benchmark thrpt 200 2.720 ± 0.089 ops/ms
Main.benchmarkFinal thrpt 200 3.133 ± 0.119 ops/ms
Main.benchmark avgt 200 0.387 ± 0.017 ms/op
Main.benchmarkFinal avgt 200 0.343 ± 0.016 ms/op
Main.benchmark sample 529790 0.377 ± 0.001 ms/op
Main.benchmark:benchmark·p0.00 sample 0.303 ms/op
Main.benchmark:benchmark·p0.50 sample 0.324 ms/op
Main.benchmark:benchmark·p0.90 sample 0.534 ms/op
Main.benchmark:benchmark·p0.95 sample 0.541 ms/op
Main.benchmark:benchmark·p0.99 sample 0.606 ms/op
Main.benchmark:benchmark·p0.999 sample 2.408 ms/op
Main.benchmark:benchmark·p0.9999 sample 4.810 ms/op
Main.benchmark:benchmark·p1.00 sample 13.386 ms/op
Main.benchmarkFinal sample 621482 0.322 ± 0.001 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.00 sample 0.254 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.50 sample 0.289 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.90 sample 0.452 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.95 sample 0.499 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.99 sample 0.523 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.999 sample 2.230 ms/op
Main.benchmarkFinal:benchmarkFinal·p0.9999 sample 3.307 ms/op
Main.benchmarkFinal:benchmarkFinal·p1.00 sample 93.323 ms/op
Main.benchmark ss 10 5.305 ± 0.391 ms/op
Main.benchmarkFinal ss 10 5.324 ± 0.278 ms/op
个人结论
测试环境
java -version
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.04 LTS
Release: 12.04
Codename: precise
可以看到,它们几乎是没有什么区别的。不过,不知道是不是自己写的测试代码有问题,如果是,还请指教。
网上大多资料显示说,它之间有性能区别,是因为它动态扩容,导致内存频率分配回收的问题。这个虽然说理论上会是这样子,但我认为,最终还是要看测试的结果。