Loading... (original) (raw)
Hi,
This issue was originally diagnosed at
http://stackoverflow.com/questions/23756966/why-is-stringbuilderappendint-faster-in-java-7-than-in-java-8
Minimizing that test case into:
@Fork(5)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class IntStr {
private int counter;
@GenerateMicroBenchmark
public String inlineSideEffect() {
return new StringBuilder().append(counter++).toString();
}
@GenerateMicroBenchmark
public String spliceSideEffect() {
int cnt = counter++;
return new StringBuilder().append(cnt).toString();
}
}
...will yield, on JDK 7u55:
Benchmark Mode Samples Mean Mean error Units
o.s.IntStr.inlineSideEffect avgt 25 65.460 1.747 ns/op
o.s.IntStr.spliceSideEffect avgt 25 64.414 1.323 ns/op
...and on JDK 8u5:
Benchmark Mode Samples Mean Mean error Units
o.s.IntStr.inlineSideEffect avgt 25 84.953 2.274 ns/op
o.s.IntStr.spliceSideEffect avgt 25 65.386 1.194 ns/op
I am pretty sure this is because
added the memory flow verification, which detected the inline increment (actually, the store part) within the StringBuilder chain and bailed out. You can see if we splice out the increment by hand, the performance is back to where it was.
Since we know the effects of StringBuilder, we can probably figure out the arguments are not dependent on SB instance state, and splice out append arguments automatically?