feat: cache date and number formatters#948
Open
Duansg wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves formatting performance by caching date/time and numeric formatter instances in thread-local maps keyed by locale + pattern, avoiding per-cell formatter construction and ensuring caches are cleared at the end of read/write lifecycles.
Changes:
- Added a
ThreadLocal<Map<String, DateTimeFormatter>>cache inDateUtilsand routed java.time parse/format through a cachedgetCacheDateTimeFormat(...). - Added a
ThreadLocal<Map<String, DecimalFormat>>cache inNumberUtils, with cleanup wired into both write and read finish paths. - Expanded unit tests to validate cache behavior across default FORMAT locale changes and to verify thread-local cleanup.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| fesod-sheet/src/main/java/org/apache/fesod/sheet/util/DateUtils.java | Adds a per-thread DateTimeFormatter cache and clears it in removeThreadLocalCache(). |
| fesod-sheet/src/main/java/org/apache/fesod/sheet/util/NumberUtils.java | Adds a per-thread DecimalFormat cache keyed by default FORMAT locale + pattern, plus public cache cleanup. |
| fesod-sheet/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java | Calls NumberUtils.removeThreadLocalCache() during write finish cleanup. |
| fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/ExcelAnalyserImpl.java | Calls NumberUtils.removeThreadLocalCache() during read finish cleanup. |
| fesod-sheet/src/test/java/org/apache/fesod/sheet/util/DateUtilsTest.java | Adds tests covering locale-sensitive DateTimeFormatter caching and cleanup verification. |
| fesod-sheet/src/test/java/org/apache/fesod/sheet/util/NumberUtilsTest.java | Adds tests covering locale-sensitive DecimalFormat caching and cleanup across read/write finishes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+95
to
+96
| @Test | ||
| void test_formatCache_tracksDefaultFormatLocaleChanges() { |
Comment on lines
+197
to
+198
| @Test | ||
| void test_dateTimeFormatterCache_distinguishesRootFromDefaultLocale() { |
Comment on lines
+216
to
+217
| @Test | ||
| void test_dateTimeFormatterCache_tracksDefaultFormatLocaleChanges() { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose of the pull request
DateUtils and NumberUtils rebuilt a formatter on every cell. This PR caches them per thread, keyed by locale + pattern, so a formatter is built once and reused.
The java.util.Date path in the very same class was already cached; the java.time and DecimalFormat paths just never got the same treatment. This PR closes that gap.
What's changed?
Both caches are ThreadLocal (not a shared static map) so they are bounded by thread lifetime and released by the existing cleanup, consistent with the sibling DATE_FORMAT_THREAD_LOCAL.
Benchmark
Checklist