I have a benchmark :
@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 StringConcatTest {
private int aInt;
@Setup
public void prepare() {
aInt = 100;
}
@Benchmark
public String emptyStringInt() {
return "" + aInt;
}
@Benchmark
public String valueOfInt() {
return String.valueOf(aInt);
}
}
And here is result :
Benchmark Mode Cnt Score Error Units
StringConcatTest.emptyStringInt thrpt 40 66045.741 ± 1306.280 ops/s
StringConcatTest.valueOfInt thrpt 40 43947.708 ± 1140.078 ops/s
It shows that concatenating of empty string with integer number is 30% faster than calling String.value(100). I understand that "" + 100 converted to
new StringBuilder().append(100).toString()
and -XX:+OptimizeStringConcat
optimization is applied that makes it fast. What I do not understand is why valueOf
itself is slower than concatenation.
Can someone explain what exactly is happening and why "" + 100 is faster. What magic does OptimizeStringConcat
make?
"" + 100
is probably much clearer for the compiler to recognize as a constant... – DelislevalueOf
. I'm pretty sure it tries to detect object types, which means autoboxing your int primitive and such – TodtodayStringBuider()
construction. – InsurrectionaryvalueOf
but It doesn't answer my question. – InsurrectionaryString.valueOf()
- the method isn't used often enough; therefore the method body is executed faithfully every time. – AluminizeString.valueOf()
has numerous overloads, which recognize the argument type at compile-time. There is no autoboxing or runtime object type detection. – Deeannadeeanne