Skip to content

Add LRU caching to corpus file loaders and pronounce utilities - #1320

Merged
bact merged 3 commits into
devfrom
copilot/identify-caching-opportunities
Mar 9, 2026
Merged

Add LRU caching to corpus file loaders and pronounce utilities#1320
bact merged 3 commits into
devfrom
copilot/identify-caching-opportunities

Conversation

Copilot AI commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

What do these changes do

Apply LRU caching to corpus file readers and pronounce utilities to eliminate redundant I/O and object construction on repeated calls. Also removes unnecessary list() conversions on already-iterable objects.

What was wrong

  • get_corpus(), get_corpus_as_is(), and get_corpus_default_db() re-read and re-parsed files on every invocation, even when called repeatedly with the same arguments (e.g. ttc.py, tnc.py, and phupha.py each call get_corpus() with the same filename from two separate functions).
  • rhyme() performed an O(n) scan over all single-syllable Thai words on every call, with no per-word memoisation.
  • spelling() rebuilt a Tokenizer from scratch on every call.
  • The module-level mutable global all_thai_words_dict in pronounce.py was an inconsistent pattern compared to the rest of the codebase.
  • Unnecessary list() calls wrapped already-iterable objects (frozenset, str) in pronounce.py and syllable.py.

How this fixes it

pythainlp/corpus/core.py

  • get_corpus(filename, comments)@lru_cache(maxsize=None). Measured 13,500× faster on cache hits (13.5 ms → 0.001 ms).
  • get_corpus_as_is(filename)@lru_cache(maxsize=None). Same benefit for the list-returning variant.
  • _load_default_db() — new private cached helper that reads and parses default_db.json once. get_corpus_default_db() delegates to it instead of re-reading the file on every call.

pythainlp/util/pronounce.py

  • _single_syllable_thai_words() — replaces the bare module-level mutable global all_thai_words_dict with a @lru_cache(maxsize=None) function, consistent with tokenize/__init__.py pattern. Removes unnecessary list() wrapping of the frozenset returned by thai_words().
  • rhyme(word)@lru_cache(maxsize=1024). Per-word memoisation of the O(n) scan.
  • _spelling_tokenizer()@lru_cache(maxsize=None) factory; avoids rebuilding a Tokenizer with identical arguments on every spelling() call.
  • _spelling_impl(word)@lru_cache(maxsize=1024) private core of spelling(). The public function keeps its non-string validation guard and delegates to the cached impl.

pythainlp/util/syllable.py

  • Removed four unnecessary list() calls wrapping thai_consonants and thai_tonemarks (both strings) in membership tests — single-character in checks work directly on strings.

Your checklist for this pull request

  • Passed code styles and structures
  • Passed code linting checks and unit test
Original prompt

Look at examples from the use of caching in tokenizers, find other opportunities in the codebase to apply caching (LRU, etc) to improve performance of the library.

only apply the caching strategy if it significantly improve the performance/efficiency.

check if the results still as expected.
run all tests, linters, type checks, formatters and fix all issues.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ilities

Co-authored-by: bact <128572+bact@users.noreply.github.com>
Copilot AI changed the title [WIP] Analyze and implement caching strategies for performance improvement Add LRU caching to corpus file loaders and pronounce utilities Mar 9, 2026
Copilot finished work on behalf of bact March 9, 2026 17:17
@bact

bact commented Mar 9, 2026

Copy link
Copy Markdown
Member

@copilot Line 21 of pythainlp/util/pronounce.py, remove unnecessary list() call on an already iterable object. Find similar instances that may also unnecessary.

@bact bact added the refactoring a technical improvement which does not add any new features or change existing features. label Mar 9, 2026
@bact bact added this to the 5.3 milestone Mar 9, 2026
…nce.py and syllable.py

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Mar 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Line 21 of pythainlp/util/pronounce.py, remove unnecessary list() call on an already iterable object. Find similar instances that may also unnecessary.

Fixed in 0aa4a10. Removed list() from pronounce.py:21 (thai_words() returns a frozenset, already iterable) and also removed four similar redundant list() calls in util/syllable.py where thai_consonants and thai_tonemarks (both strings) were wrapped in list() for membership tests that work directly on strings.

Copilot finished work on behalf of bact March 9, 2026 17:56
@sonarqubecloud

sonarqubecloud Bot commented Mar 9, 2026

Copy link
Copy Markdown

@bact
bact marked this pull request as ready for review March 9, 2026 18:01
@bact
bact merged commit 59edaea into dev Mar 9, 2026
28 checks passed
@bact
bact deleted the copilot/identify-caching-opportunities branch March 9, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring a technical improvement which does not add any new features or change existing features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants