Skip to content

perf(semantic): use SIMD for finding backslashes in check_string_literal#17534

Merged
graphite-app[bot] merged 1 commit into
mainfrom
12-31-perf_semantic_experiment
Dec 31, 2025
Merged

perf(semantic): use SIMD for finding backslashes in check_string_literal#17534
graphite-app[bot] merged 1 commit into
mainfrom
12-31-perf_semantic_experiment

Conversation

@camchenry

@camchenry camchenry commented Dec 31, 2025

Copy link
Copy Markdown
Member

Profiling shows that check_string_literal is called fairly often. We use a naive byte-by-byte check here for finding backslashes for octal escape sequences. This should be optimized to something wider than processing a single byte at a time, but it's worth ensuring this actually happens.

This PR changes it so that when the minimum string length is met, we use the SIMD-optimized memchr crate to find backslashes instead.

image

@github-actions github-actions Bot added A-semantic Area - Semantic C-performance Category - Solution not expected to change functional behavior, only performance labels Dec 31, 2025

camchenry commented Dec 31, 2025

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codspeed-hq

codspeed-hq Bot commented Dec 31, 2025

Copy link
Copy Markdown

CodSpeed Performance Report

Merging #17534 will not alter performance

Comparing 12-31-perf_semantic_experiment (203ee7f) with main (5cc2db6)

Summary

✅ 42 untouched
⏩ 3 skipped1

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@camchenry
camchenry force-pushed the 12-31-perf_semantic_experiment branch 2 times, most recently from b1708a6 to 203ee7f Compare December 31, 2025 18:51
@camchenry camchenry changed the title perf(semantic): experiment perf(semantic): use SIMD for finding backslashes in check_string_literal Dec 31, 2025
@camchenry
camchenry marked this pull request as ready for review December 31, 2025 19:20
@camchenry
camchenry requested a review from Dunqing as a code owner December 31, 2025 19:20
Copilot AI review requested due to automatic review settings December 31, 2025 19:20

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 performance of check_string_literal by using SIMD instructions for detecting backslashes in string literals. Profiling identified this function as a hot path that was using a naive byte-by-byte scan.

Key changes:

  • Introduces a two-path approach: SIMD-optimized memchr for strings ≥16 bytes, byte-by-byte fallback for smaller strings
  • Adds early return for non-strict mode to avoid unnecessary processing
  • Changes from character-based to byte-based processing (safe for ASCII escape sequences)

Reviewed changes

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

File Description
crates/oxc_semantic/src/checker/javascript.rs Implements dual-path string literal checking with SIMD optimization for longer strings and maintains byte-by-byte fallback for shorter strings
crates/oxc_semantic/Cargo.toml Adds memchr dependency for SIMD-optimized searching
Cargo.lock Updates lock file with memchr dependency and incidental version bumps for cc and find-msvc-tools

After thoroughly reviewing this PR, I found the implementation to be correct and well-designed:

Logic Correctness: I verified the escape sequence handling logic through extensive analysis of edge cases, including:

  • Escaped backslashes (\\)
  • Multiple consecutive backslashes
  • Octal escape sequences (\0 through \7)
  • Non-octal decimal escapes (\8 and \9)
  • The skip_next_backslash mechanism correctly handles escaped backslashes in the SIMD path

Design Decisions: The code duplication between the SIMD and fallback paths is intentional and acceptable for a performance optimization. The 16-byte threshold appears reasonable for SIMD overhead, and memchr is already used elsewhere in the codebase, demonstrating consistency with project practices.

Behavioral Equivalence: Both paths produce identical results, and the early return optimization for non-strict mode is a sensible improvement that avoids unnecessary work.

No issues requiring comments were identified.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/oxc_semantic/src/checker/javascript.rs
Comment thread crates/oxc_semantic/src/checker/javascript.rs
@camc314 camc314 self-assigned this Dec 31, 2025

@camc314 camc314 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.

nice work!

@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Dec 31, 2025

camc314 commented Dec 31, 2025

Copy link
Copy Markdown
Contributor

Merge activity

…eral` (#17534)

Profiling shows that `check_string_literal` is called fairly often. We use a naive byte-by-byte check here for finding backslashes for octal escape sequences. This should be optimized to something wider than processing a single byte at a time, but it's worth ensuring this actually happens.

This PR changes it so that when the minimum string length is met, we use the SIMD-optimized `memchr` crate to find backslashes instead.

<img width="696" height="352" alt="image" src="https://github.com/user-attachments/assets/58c67f78-7b91-4ab1-aa45-68a175c38e6c" />
@graphite-app
graphite-app Bot force-pushed the 12-31-perf_semantic_experiment branch from 203ee7f to 04809d1 Compare December 31, 2025 21:25
@graphite-app
graphite-app Bot merged commit 04809d1 into main Dec 31, 2025
21 checks passed
@graphite-app
graphite-app Bot deleted the 12-31-perf_semantic_experiment branch December 31, 2025 21:31
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Dec 31, 2025
graphite-app Bot pushed a commit that referenced this pull request Jan 5, 2026
### 🚀 Features

- 659c23e linter: Init note field boilerplate  (#17589) (Shrey Sudhir)
- 6870b64 parser: Add TS1363 error code (#17609) (Sysix)
- 23680a3 mangler: Skip mangling only in scopes affected by direct eval (#17612) (camc314)
- a7e1643 parser: Add TS2528 error code to duplicate_default_export diagnostic (#17558) (camc314)

### 🐛 Bug Fixes

- 1044116 ecmascript: Mark `new Symbol` as non side-effect free (#17568) (camc314)
- ab5e4ca isolated-declarations: Strip default values from rest parameter binding patterns (#17602) (camc314)
- 68b2e54 minifier: Prevent incorrect ??= transformation when member base is mutated (#17472) (copilot-swe-agent)

### ⚡ Performance

- 6067143 semantic: Remove hash when checking identifier (#17564) (camchenry)
- a28ab3d semantic: Avoid bounds check when checking string literal (#17545) (camc314)
- 04809d1 semantic: Use SIMD for finding backslashes in `check_string_literal` (#17534) (camchenry)
- 49ad2f0 semantic: Mark all diagnostic functions as `#[cold]` (#17487) (camc314)
- ea82b50 transformer: Mark all diagnostic functions as `#[cold]` (#17486) (camc314)
- d968e51 semantic: Mark `checker::check` as `inline(always)` (#17459) (camc314)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-semantic Area - Semantic C-performance Category - Solution not expected to change functional behavior, only performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants