Dlaczego Łańcuch StringBuilder ma wzór sb.append(x).Dołącz(y) szybciej niż zwykły sb.append( x); sb.Dołącz(y)?
Mam mikrobenchmark, który pokazuje bardzo dziwne wyniki:
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
@Measurement(iterations = 40, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
public class Chaining {
private String a1 = "111111111111111111111111";
private String a2 = "222222222222222222222222";
private String a3 = "333333333333333333333333";
@Benchmark
public String typicalChaining() {
return new StringBuilder().append(a1).append(a2).append(a3).toString();
}
@Benchmark
public String noChaining() {
StringBuilder sb = new StringBuilder();
sb.append(a1);
sb.append(a2);
sb.append(a3);
return sb.toString();
}
}
Spodziewam się, że wyniki obu testów będą takie same lub przynajmniej bardzo zbliżone. Jednak różnica jest prawie 5x:
# Run complete. Total time: 00:01:41
Benchmark Mode Cnt Score Error Units
Chaining.noChaining thrpt 40 8538.236 ± 209.924 ops/s
Chaining.typicalChaining thrpt 40 36729.523 ± 988.936 ops/s
Czy ktoś wie jak to jest możliwe? 1 answers
String concatenation a + b + c
jest bardzo częstym wzorcem w programach Java, więc HotSpot JVM ma dla niego specjalną optymalizację: -XX:+OptimizeStringConcat
, która jest domyślnie włączona.
HotSpot JVM rozpoznaje wzorzec new StringBuilder().append()...append().toString()
w kodzie bajtowym i tłumaczy go na zoptymalizowany kod maszynowy bez wywoływania rzeczywistych metod Javy i bez przydzielania obiektów pośrednich. Jest to rodzaj złożonego JVM wewnętrznego.
Oto kod źródłowy do tej optymalizacji.
Po drugiej stronie, sb.append(); sb.append(); ...
nie jest obsługiwany specjalnie. Sekwencja ta jest kompilowana tak jak zwykłe wywołania metody Java.
Jeśli powtórzysz test z -XX:-OptimizeStringConcat
, wydajność będzie taka sama dla obu wariantów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-03 01:19:59