We're updating the issue view to help you get more done. 

Add locale caching to NumberFormatter


For users who are concerned with performance, there are intended to be two primary patterns for NumberFormatter call sites:

1 2 3 4 5 6 7 8 9 10 // When locale is unknown until the call site (e.g., servers): static final UnlocalizedNumberFormatter template = NumberFormatter.with() .setting1() .setting2(); // Call site: template.locale(locale) .format(number) .toString();


1 2 3 4 5 6 7 8 9 // When locale is known at startup (e.g., devices): static final LocalizedNumberFormatter formatter = NumberFormatter.withLocale(locale) .setting1() .setting2(); // Call site: formatter.format(number) .toString();

The second case, devices, benefits from the "lazy self-regulation" described in the design doc: after the `.format()` method is called several times, intermediate data structures will be allocated and saved to improve performance.

However, in the first case, since `.format()` gets called on a new instance each time, there is no caching that takes place.

To fix this, I see two approaches:

1. Make UnlocalizedNumberFormatter lazy-cache instances of LocalizedNumberFormatter that were created from it via the `.locale()` method.
2. Make all NumberFormatters (both localized and unlocalized) lazy-cache child objects created from fluent methods. This would increase heap usage but would also make "inline" NumberFormatter chains more efficient, to the point that we would no longer need to recommend users to static-allocate their formatters.


1. The caching would work fine in Java, but it is not clear how it ports to C++ since formatters are stored by value.
2. Some users are concerned with ICU4J's heap memory usage. We would need to discuss whether we want to run the caching by default (with an optional opt-out) or whether we want to make it opt-in instead.



Shane Carr


Shane Carr

Time Needed



Fix versions