Konkatenacja czy StringBuilder? – benchmark test

Konkatenacja czy StringBuilder? – benchmark test

Ten wpis ma na celu porównanie metod konkatenacji Stringów z użyciem testów benchmarkowych. Zanim jednak zaczniesz czytać ten wpis polecam Ci zapoznać się z moim artykułem w którym opisuje czym są jak pisać dobre testy benchmarkowe – https://javaleader.pl/2019/12/12/java-microbenchmark-harness-jmh/. Testy zostaną przeprowadzone z użyciem klas StringBuilder, StringBuffer oraz operatora konkatenacji +.

Klasa poddana testom:

public class ConcatString {
 
    public static String concatByStringBuilder() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        return stringBuilder.toString();
    }
 
    public static String concatByStringBuffer() {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 1000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        return stringBuffer.toString();
    }
 
    public static String concatByPlusOperator() {
        String result = "";
        for (int i = 0; i < 1000; i++) {
            result +=  String.valueOf(i);
        }
        return result;
    }
}

Testy benchmarkowe:

public class BenchmarkConcatTest {
 
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    @Fork(value = 1)
    @Warmup(iterations = 3, time = 1)
    @Measurement(iterations = 5, time = 1)
    public String testConcatByStringBuilder() {
        return ConcatString.concatByStringBuilder();
    }
 
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    @Fork(value = 1)
    @Warmup(iterations = 3, time = 1)
    @Measurement(iterations = 5, time = 1)
    public String testConcatByStringBuffer() {
        return ConcatString.concatByStringBuffer();
    }
 
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    @Fork(value = 1)
    @Warmup(iterations = 3, time = 1)
    @Measurement(iterations = 5, time = 1)
    public String testConcatByPlusOperator() {
        return ConcatString.concatByPlusOperator();
    }
 
}

wynik:

Benchmark                                      Mode  Cnt    Score    Error  Units
BenchmarkConcatTest.testConcatByPlusOperator   avgt    5  735,701 ± 45,396  us/op
BenchmarkConcatTest.testConcatByStringBuffer   avgt    5   27,585 ±  7,291  us/op
BenchmarkConcatTest.testConcatByStringBuilder  avgt    5   14,726 ±  1,573  us/op

Wyniki jasno pokazują, że użycie operatora konkatenacji w Javie jest znacznie mniej wydajne niż użycie klasy StringBuilder. StringBuffer natomiast ze względu na to, że jest to klasa bezpieczna wątkowo jest mniej wydajny niż StringBuilder. Nie używajmy zatem operatora + do łączenia ciągów tekstowych! Zamiast tego powinniśmy używać klasy StringBuilder.

Zobacz kod na GitHubie i zapisz się na bezpłatny newsletter!

.

Leave a comment

Your email address will not be published.


*