> We need a String format solution with good performance. String Template was > once expected, but it has been removed. j.u.Formatter is powerful, but its > performance is not good enough. > > This PR implements a subset of j.u.Formatter capabilities. The performance is > good enough that it is a fastpath for commonly used functions. When the > supported functions are exceeded, it will fall back to using j.u.Formatter. > > The performance of this implementation is good enough, the fastpath has low > detection cost, There is no noticeable performance degradation when falling > back to j.u.Formatter via fastpath. > > Below is a comparison of String.format and concat-based and StringBuilder: > > * benchmark java code > > public class StringFormat { > @Benchmark > public String stringIntFormat() { > return "%s %d".formatted(s, i); > } > > @Benchmark > public String stringIntConcat() { > return s + " " + i; > } > > @Benchmark > public String stringIntStringBuilder() { > return new StringBuilder(s).append(" ").append(i).toString(); > } > } > > > * benchmark number on macbook m1 pro > > Benchmark Mode Cnt Score Error Units > StringFormat.stringIntConcat avgt 15 6.541 ? 0.056 ns/op > StringFormat.stringIntFormat avgt 15 17.399 ? 0.133 ns/op > StringFormat.stringIntStringBuilder avgt 15 8.004 ? 0.063 ns/op > > > From the above data, we can see that the implementation of fastpath reduces > the performance difference between String.format and StringBuilder from 10 > times to 2~3 times. > > The implementation of fastpath supports the following four specifiers, which > can appear at most twice and support a width of 1 to 9. > > d > x > X > s > > If necessary, we can add a few more. > > > Below is a comparison of performance numbers running on a MacBook M1, showing > a significant performance improvement. > > -Benchmark Mode Cnt Score Error Units > (baseline) > -StringFormat.complexFormat avgt 15 895.954 ? 52.541 ns/op > -StringFormat.decimalFormat avgt 15 277.420 ? 18.254 ns/op > -StringFormat.stringFormat avgt 15 66.787 ? 2.715 ns/op > -StringFormat.stringIntFormat avgt 15 81.046 ? 1.879 ns/op > -StringFormat.widthStringFormat avgt 15 38.897 ? 0.114 ns/op > -StringFormat.widthStringIntFormat avgt 15 109.841 ? 1.028 ns/op > > +Benchmark Mode Cnt Score Error Units > (current f925339e93fdf7a281462554ce5d73139bd0f0cd) > +StringFormat.complexF...
Shaojin Wen has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 19 additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into optim_str_format_202407_fastpath - last specifier support %n - optimize width padding - improve StringFormat benchmark - add more test - add StringFormat test - code style - Update src/java.base/share/classes/java/lang/StringFormat.java Co-authored-by: David Schlosnagle <schlo...@gmail.com> - laze init for `decimal fast path locale` - isBigInt -> isLong - ... and 9 more: https://git.openjdk.org/jdk/compare/e840c78a...7313cdbd ------------- Changes: - all: https://git.openjdk.org/jdk/pull/19956/files - new: https://git.openjdk.org/jdk/pull/19956/files/f1ae26a0..7313cdbd Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=19956&range=13 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=19956&range=12-13 Stats: 35144 lines in 1152 files changed: 21627 ins; 8503 del; 5014 mod Patch: https://git.openjdk.org/jdk/pull/19956.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/19956/head:pull/19956 PR: https://git.openjdk.org/jdk/pull/19956