Skip to content

perf(utf8): reduce lossy decode output allocation - #4143

Merged
peter-jerry-ye merged 2 commits into
moonbitlang:mainfrom
mizchi:perf/utf8-lossy-output-allocation
Aug 26, 2026
Merged

perf(utf8): reduce lossy decode output allocation#4143
peter-jerry-ye merged 2 commits into
moonbitlang:mainfrom
mizchi:perf/utf8-lossy-output-allocation

Conversation

@mizchi

@mizchi mizchi commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Size the non-JS decode_lossy UTF-16 scratch array to the input byte length instead of twice that length: one UTF-8 byte can produce at most one UTF-16 code unit, including replacement characters for malformed input. When decoding fills the scratch array exactly, reuse it as the result instead of allocating and copying again.

This also halves peak scratch storage.

Benchmark

Native release, 1,000,000 input bytes:

Input Before After
ASCII 244.18 us 97.66 us
all invalid 3.39 ms 2.87 ms
mixed 1/2/3/4-byte UTF-8 830.00 us 669.27 us

Validation

  • moon test encoding/utf8 --target all
  • moon check
  • moon info (no interface changes)

Copilot AI lite review requested due to automatic review settings August 24, 2026 17:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the non-JS UTF-8 decode_lossy implementation by reducing UTF-16 scratch buffer over-allocation and avoiding an extra allocation/copy when the scratch buffer is filled exactly, improving throughput and peak memory usage.

Changes:

  • Size the non-JS decode_lossy UTF-16 scratch FixedArray[UInt16] to src_length (instead of src_length * 2).
  • Reuse the scratch buffer as the final result when written == src_length to avoid allocating/copying.
  • Add benchmark tests for decode_lossy and include the bench test dependency.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
encoding/utf8/moon.pkg Adds moonbitlang/core/bench as a test-only dependency to support new benchmarks.
encoding/utf8/decode_nonjs.mbt Reduces scratch allocation for decode_lossy and reuses scratch when fully utilized to avoid extra allocation/copy.
encoding/utf8/decode_lossy_bench_test.mbt Adds benchmark coverage for ASCII, invalid, and mixed UTF-8 inputs at 1,000,000 bytes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@peter-jerry-ye
peter-jerry-ye force-pushed the perf/utf8-lossy-output-allocation branch from f70acc0 to 7eb876d Compare August 26, 2026 08:38
@peter-jerry-ye
peter-jerry-ye enabled auto-merge (rebase) August 26, 2026 09:26
@peter-jerry-ye
peter-jerry-ye merged commit 6deec13 into moonbitlang:main Aug 26, 2026
16 checks passed
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.

3 participants