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?
 
     
    