Skip to content

Instantly share code, notes, and snippets.

@douglarek
Last active March 9, 2021 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglarek/6085957eae1acfeecee4a0185d594ede to your computer and use it in GitHub Desktop.
Save douglarek/6085957eae1acfeecee4a0185d594ede to your computer and use it in GitHub Desktop.
java stringBuilder vs stringConcat with JMH
# JMH version: 1.28
# VM version: JDK 11.0.10, OpenJDK 64-Bit Server VM, 11.0.10+9-Ubuntu-0ubuntu1.20.04
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: <none>
# Blackhole mode: full + dont-inline hint
# Warmup: 3 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.stringBuilder
# Parameters: (count = 100)
# Run progress: 0.00% complete, ETA 00:05:20
# Fork: 1 of 1
# Warmup Iteration 1: 0.403 ms/op
# Warmup Iteration 2: 0.987 ms/op
# Warmup Iteration 3: 1.331 ms/op
Iteration 1: 1.639 ms/op
Iteration 2: 1.882 ms/op
Iteration 3: 2.250 ms/op
Iteration 4: 2.111 ms/op
Iteration 5: 2.323 ms/op
Result "org.sample.MyBenchmark.stringBuilder":
2.041 ±(99.9%) 1.079 ms/op [Average]
(min, avg, max) = (1.639, 2.041, 2.323), stdev = 0.280
CI (99.9%): [0.962, 3.120] (assumes normal distribution)
# JMH version: 1.28
# VM version: JDK 11.0.10, OpenJDK 64-Bit Server VM, 11.0.10+9-Ubuntu-0ubuntu1.20.04
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: <none>
# Blackhole mode: full + dont-inline hint
# Warmup: 3 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.stringBuilder
# Parameters: (count = 10000)
# Run progress: 25.00% complete, ETA 00:04:00
# Fork: 1 of 1
# Warmup Iteration 1: 6.367 ms/op
# Warmup Iteration 2: 17.183 ms/op
# Warmup Iteration 3: 22.627 ms/op
Iteration 1: 27.120 ms/op
Iteration 2: 29.092 ms/op
Iteration 3: 31.841 ms/op
Iteration 4: 34.816 ms/op
Iteration 5: 36.769 ms/op
Result "org.sample.MyBenchmark.stringBuilder":
31.928 ±(99.9%) 15.274 ms/op [Average]
(min, avg, max) = (27.120, 31.928, 36.769), stdev = 3.967
CI (99.9%): [16.653, 47.202] (assumes normal distribution)
# JMH version: 1.28
# VM version: JDK 11.0.10, OpenJDK 64-Bit Server VM, 11.0.10+9-Ubuntu-0ubuntu1.20.04
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: <none>
# Blackhole mode: full + dont-inline hint
# Warmup: 3 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.stringConcat
# Parameters: (count = 100)
# Run progress: 50.00% complete, ETA 00:02:40
# Fork: 1 of 1
# Warmup Iteration 1: 4.259 ms/op
# Warmup Iteration 2: 8.805 ms/op
# Warmup Iteration 3: 11.861 ms/op
Iteration 1: 13.923 ms/op
Iteration 2: 16.093 ms/op
Iteration 3: 18.706 ms/op
Iteration 4: 21.460 ms/op
Iteration 5: 21.314 ms/op
Result "org.sample.MyBenchmark.stringConcat":
18.299 ±(99.9%) 12.664 ms/op [Average]
(min, avg, max) = (13.923, 18.299, 21.460), stdev = 3.289
CI (99.9%): [5.636, 30.963] (assumes normal distribution)
# JMH version: 1.28
# VM version: JDK 11.0.10, OpenJDK 64-Bit Server VM, 11.0.10+9-Ubuntu-0ubuntu1.20.04
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: <none>
# Blackhole mode: full + dont-inline hint
# Warmup: 3 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.stringConcat
# Parameters: (count = 10000)
# Run progress: 75.00% complete, ETA 00:01:20
# Fork: 1 of 1
# Warmup Iteration 1: 1128.453 ms/op
# Warmup Iteration 2: 1100.954 ms/op
# Warmup Iteration 3: 1462.695 ms/op
Iteration 1: 1983.978 ms/op
Iteration 2: 2379.345 ms/op
Iteration 3: 2521.124 ms/op
Iteration 4: 2744.632 ms/op
Iteration 5: 2943.203 ms/op
Result "org.sample.MyBenchmark.stringConcat":
2514.456 ±(99.9%) 1410.239 ms/op [Average]
(min, avg, max) = (1983.978, 2514.456, 2943.203), stdev = 366.234
CI (99.9%): [1104.218, 3924.695] (assumes normal distribution)
# Run complete. Total time: 00:05:32
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.
Benchmark (count) Mode Cnt Score Error Units
MyBenchmark.stringBuilder 100 avgt 5 2.041 ± 1.079 ms/op
MyBenchmark.stringBuilder 10000 avgt 5 31.928 ± 15.274 ms/op
MyBenchmark.stringConcat 100 avgt 5 18.299 ± 12.664 ms/op
MyBenchmark.stringConcat 10000 avgt 5 2514.456 ± 1410.239 ms/op
/*
* Copyright (c) 2014, Oracle America, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Oracle nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.sample;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
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;
@BenchmarkMode({ Mode.AverageTime })
@State(Scope.Thread)
@Fork(1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
public class MyBenchmark {
@Param({ "100", "10000" })
private int count;
private String s;
private StringBuilder sb;
@Setup
public void setUp() {
s = "";
sb = new StringBuilder();
}
@Benchmark
public String stringConcat() {
for (int i = 0; i < count; i++) {
s += i;
}
return s;
}
@Benchmark
public String stringBuilder() {
for (int i = 0; i < count; i++) {
sb.append(i);
}
return sb.toString();
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder().include(MyBenchmark.class.getSimpleName()).build();
new Runner(options).run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment