The return type of expression (c == '"' && !escaped) ? "\\\"" : c is Object, which implies a call to StringBuilder.append(Object).
The implementation of the following means that lots of garbage objects are allocated as a result of String.valueOf().
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
Instead of covariant append we can use exact signatures, i.e. one taking char and one taking String which allows us to avoid unnecessary allocations.
This benchmark demonstrates significant improvement even for filename of length = 10:
JDK 8
Benchmark (latin) (length) Mode Cnt Score Error Units
appendCovariant true 10 avgt 50 180.230 ± 10.346 ns/op
appendExact true 10 avgt 50 68.517 ± 1.479 ns/op
appendCovariant false 10 avgt 50 177.713 ± 4.438 ns/op
appendExact false 10 avgt 50 67.798 ± 1.364 ns/op
appendCovariant:·gc.alloc.rate.norm true 10 avgt 50 688.000 ± 0.001 B/op
appendExact:·gc.alloc.rate.norm true 10 avgt 50 112.000 ± 0.001 B/op
appendCovariant:·gc.alloc.rate.norm false 10 avgt 50 816.000 ± 0.001 B/op
appendExact:·gc.alloc.rate.norm false 10 avgt 50 112.000 ± 0.001 B/op
JDK 14
Benchmark (latin) (length) Mode Cnt Score Error Units
appendCovariant true 10 avgt 50 228.858 ± 18.627 ns/op
appendExact true 10 avgt 50 57.950 ± 2.660 ns/op
appendCovariant false 10 avgt 50 292.879 ± 12.408 ns/op
appendExact false 10 avgt 50 90.228 ± 2.277 ns/op
appendCovariant:·gc.alloc.rate.norm true 10 avgt 50 688.026 ± 0.002 B/op
appendExact:·gc.alloc.rate.norm true 10 avgt 50 112.004 ± 0.001 B/op
appendCovariant:·gc.alloc.rate.norm false 10 avgt 50 1096.040 ± 0.002 B/op
appendExact:·gc.alloc.rate.norm false 10 avgt 50 200.008 ± 0.001 B/op
Comment From: sbrannen
This has been merged into master.
Thanks
Comment From: rstoyanchev
Good catch!