Skip to content

extend grapheme_category fast path - #179

Open
cometkim wants to merge 1 commit into
unicode-rs:masterfrom
cometkim:inline-ranges-2
Open

extend grapheme_category fast path#179
cometkim wants to merge 1 commit into
unicode-rs:masterfrom
cometkim:inline-ranges-2

Conversation

@cometkim

@cometkim cometkim commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Context: #177


Based on observations of UCD data, inlined other ranges that can be easily derived at runtime, in addition to ASCII.

  • [0x30A0, 0xA660): CJK...Vai. All Any, except U+3297/U+3299 (Extended_Pictographic)
  • [0xAC00, 0xD7A4): Hangul syllables, LV every 28th and LVT otherwise
  • [0xFE00, 0xFE10): Variation selectors, all Extend

Inlining the evaluation of these ranges allows us to omit ranges from the data in tables.rs.

The largest range is Hangul syllables, which corresponds to 599 table entries and 16,173 code points, representing 53% of the existing grapheme_cat_table.

It can be replaced by a single O(1) modulo operation, which is beneficial to other ranges as well, as it reduces the number of comparisons in the worst-case table search by one.

Although there is a slight overhead because inline ranges are always evaluated, this loss is offset by an improved cache hit rate, as they are excluded from the range cache.

There are a few more derivable ranges, but they are less effective.

Based on observations of UCD data, inlined other ranges
that can be easily derived at runtime, in addition to ASCII.

- `[0x30A0, 0xA660)`: CJK...Vai. All `Any`, except `U+3297`/`U+3299` (`Extended_Pictographic`)
- `[0xAC00, 0xD7A4)`: Hangul syllables, `LV` every 28th and `LVT` otherwise
- `[0xFE00, 0xFE10)`: Variation selectors, all `Extend`

Inlining the evaluation of these ranges allows us to omit ranges from the data in `tables.rs`.

The largest range is Hangul syllables, which corresponds to 599 table entries and 16,173 code points,
representing 53% of the existing `grapheme_cat_table`.

It can be replaced by a single O(1) modulo operation, which is beneficial to other ranges as well,
as it reduces the number of comparisons in the worst-case table search by one.

Although there is a slight overhead because inline ranges are always evaluated,
this loss is offset by an improved cache hit rate, as they are excluded from the range cache.

There are a few more derivable ranges, but they are less effective.
@cometkim

cometkim commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

I relocated the ASCII path to the same location.

Since Unicode range assumptions are checked in unicode.py, utilizing these assumptions must also be done there, and the grapheme.rs wrapper performs only cache instancing and integration. The GraphemeCategoryResult enum is added for that.

Comment thread src/grapheme.rs
if (ch as u32) < self.grapheme_cat_cache.0 || (ch as u32) > self.grapheme_cat_cache.1 {
self.grapheme_cat_cache = gr::grapheme_category(ch);

match gr::grapheme_category(ch) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the codegen makes the changes look a bit inflated, but the key is a single change to the grapheme_category function integration here.

@Manishearth

Copy link
Copy Markdown
Member

This is a pretty large diff, I do not think I will have time to review this any time soon. If you can get another maintainer or a trusted community member to review it I could perhaps perform a faster review, but at the moment I'm probably going to heavily deprioritize this.

@cometkim

cometkim commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Hmm. If I exclude the safety check in the Python code, the diff to review can be significantly reduced. That part isn't really mandatory if the existing Unicode range doesn't change.

@Manishearth

Copy link
Copy Markdown
Member

I think the consistency check is necessary: we need to be able to make sure things are handled on updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants