被测试代码

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

可以看到,它们几乎是没有什么区别的。不过,不知道是不是自己写的测试代码有问题,如果是,还请指教。

网上大多资料显示说,它之间有性能区别,是因为它动态扩容,导致内存频率分配回收的问题。这个虽然说理论上会是这样子,但我认为,最终还是要看测试的结果。