Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .changeset/huge-hotels-ask.md

This file was deleted.

21 changes: 0 additions & 21 deletions .changeset/smooth-dragons-notice.md

This file was deleted.

26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# unicode-segmenter

## 0.17.2

### Patch Changes

- 7374446: Removed pinned `graphemeSegments()` in the module scope to make all APIs able to be three-shaken properly.

It was introduced when they all use `graphemeSegments()` as the core. But now they are all have their own loop.

- 957898b: Optimize the hot loop based on a deep analysis of the V8 optimization chain.

As the result, the bundle size, speed, and memory usage. All three axes are improved. See PR [#144](https://github.com/cometkim/unicode-segmenter/pull/144) for detailed explanation.

- Bundle: −4.2% min+gzip, −3.9% min+brotli on `unicode-segmenter/grapheme` (2,453 → 2,351 gzip); −3.4% / −2.8% on the full entry
- Hermes bytecode: −20.6% (20,015 → 15,892 bytes), −18.6% gzipped
- Runtime (Node.js/V8, per benchmark case)
- `splitGraphemes()` 1.5–2.2x, `countGraphemes()` 1.20–1.43x, `graphemeSegments()` 1.05–1.21x, `collectGraphemes()` 1.01–1.19x.
- Bun/JSC gains are larger, and the interpreter tiers (Hermes, QuickJS) improve 5–23%
- Memory: lookup tables 20.6 kB → 19.1 kB, retained heap 228 kB → 218 kB, module init 1.7 ms → 1.5 ms

The state compaction strategy is the major part. It is valid across all optimization tiers of the V8 runtime (Jitless, Maglev, TurboFan) and has been consistently improved across all other engines.

Another noticeable change is `splitGraphemes()`, it now owns its loop, just like `countGraphemes()`.
It produces a 30-60% performance improvement. The size increase is roughly free after compression, since the fourth byte-aligned copy of the loop back-references the other three. And the uncompressed size is amortized by other improvements.

All the analysis have done by Claude Opus 5, well-done!

## 0.17.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "unicode-segmenter",
"version": "0.17.1",
"version": "0.17.2",
"type": "module",
"description": "A lightweight implementation of the Unicode Text Segmentation (UAX #29)",
"license": "MIT",
Expand Down
Loading