On Fri, 4 Mar 2022 17:54:20 GMT, Jim Laskey <jlas...@openjdk.org> wrote:

> Several attempts have been made to improve Formatter's numeric performance by 
> caching the current Locale zero. Such fixes, however, ignore the real issue, 
> which is the slowness of fetching DecimalFormatSymbols. By directly caching 
> DecimalFormatSymbols in the Formatter, this enhancement streamlines the 
> process of accessing Locale DecimalFormatSymbols and specifically 
> getZeroDigit(). The result is a general improvement in the performance of 
> numeric formatting. 
> 
> 
> @Benchmark 
> public void bigDecimalDefaultLocale() { 
>     result = String.format("%1$f %1$f %1$f %1$f %1$f %1$f %1$f %1$f %1$f 
> %1$f", X); 
> } 
> 
> @Benchmark 
> public void bigDecimalLocaleAlternate() { 
>     result = String.format(THAI, "%1$f %1$f %1$f %1$f %1$f %1$f %1$f %1$f 
> %1$f %1$f", X); 
>     other = String.format(DEFAULT, "%1$f %1$f %1$f %1$f %1$f %1$f %1$f %1$f 
> %1$f %1$f", X); 
> } 
> 
> @Benchmark 
> public void bigDecimalThaiLocale() { 
>     result = String.format(THAI, "%1$f %1$f %1$f %1$f %1$f %1$f %1$f %1$f 
> %1$f %1$f", X); 
> } 
> 
> @Benchmark 
> public void integerDefaultLocale() { 
>     result = String.format("%1$d %1$d %1$d %1$d %1$d %1$d %1$d %1$d %1$d 
> %1$d", x); 
> } 
> 
> @Benchmark 
> public void integerLocaleAlternate() { 
>     result = String.format(THAI, "%1$d %1$d %1$d %1$d %1$d %1$d %1$d %1$d 
> %1$d %1$d", x); 
>     other = String.format(DEFAULT, "%1$d %1$d %1$d %1$d %1$d %1$d %1$d %1$d 
> %1$d %1$d", x); 
> } 
> 
> @Benchmark 
> public void integerThaiLocale() { 
>     result = String.format(THAI, "%1$d %1$d %1$d %1$d %1$d %1$d %1$d %1$d 
> %1$d %1$d", x); 
> } 
> 
> 
> Before: 
> Benchmark Mode Cnt Score Error Units 
> MyBenchmark.bigDecimalDefaultLocale thrpt 25 75498.923 ± 3686.966 ops/s 
> MyBenchmark.bigDecimalLocaleAlternate thrpt 25 39068.721 ± 162.983 ops/s 
> MyBenchmark.bigDecimalThaiLocale thrpt 25 77256.530 ± 294.743 ops/s 
> MyBenchmark.integerDefaultLocale thrpt 25 344093.071 ± 6189.002 ops/s 
> MyBenchmark.integerLocaleAlternate thrpt 25 165685.488 ± 440.857 ops/s 
> MyBenchmark.integerThaiLocale thrpt 25 327461.302 ± 1168.243 ops/s 
> 
> After: 
> Benchmark Mode Cnt Score Error Units 
> MyBenchmark.bigDecimalDefaultLocale thrpt 25 94735.293 ± 674.587 ops/s 
> MyBenchmark.bigDecimalLocaleAlternate thrpt 25 44215.547 ± 291.664 ops/s 
> MyBenchmark.bigDecimalThaiLocale thrpt 25 91390.997 ± 658.677 ops/s 
> MyBenchmark.integerDefaultLocale thrpt 25 363722.977 ± 2864.554 ops/s 
> MyBenchmark.integerLocaleAlternate thrpt 25 165789.514 ± 779.656 ops/s 
> MyBenchmark.integerThaiLocale thrpt 25 351400.818 ± 1030.246 ops/s

Good to see the performance improvement. Since you are adding a new public 
method, a CSR is needed for this change.

src/java.base/share/classes/java/text/DecimalFormatSymbols.java line 194:

> 192:      * Gets the locale used to create this table.
> 193:      *
> 194:      * @return the the locale used to create this table

`table` does not read right here, also `@since 19` is needed.

src/java.base/share/classes/java/util/Formatter.java line 2016:

> 2014:     static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) {
> 2015:         DecimalFormatSymbols dfs = DFS;
> 2016:         if (dfs != null && dfs.getLocale() == locale) {

`Locale` should be compared using `equals()`.

src/java.base/share/classes/java/util/Formatter.java line 2026:

> 2024:     // Caching zero.
> 2025:     static char getZero(Locale locale) {
> 2026:         return locale == null ? '0' : 
> getDecimalFormatSymbols(locale).getZeroDigit();

While we are at it, it would be beneficial to cache locale-dependent grouping 
and decimal separators too.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7703

Reply via email to