Skip to content

Commit b5fa195

Browse files
committed
perf(codegen): remove bounds check from SourcemapBuilder (#19578)
Follow-on after #19548. Remove a bounds check from hot loop in `SourcemapBuilder::update_generated_line_and_column` by doing only 1 bounds check to get next 2 bytes, instead of 2 bounds checks for each byte. This optimization was taken from @cam314's original version of PR #19548. While reviewing that PR I also thought I'd spied 2 other optimizations, but on reflection, I realized they were better left as is. Add comments to explain why.
1 parent e316694 commit b5fa195

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

crates/oxc_codegen/src/sourcemap_builder.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,17 @@ impl<'a> SourcemapBuilder<'a> {
254254
continue;
255255
}
256256
LS_OR_PS_FIRST_BYTE => {
257-
let next_byte = output[idx + 1];
258-
let next_next_byte = output[idx + 2];
259-
if !matches!([next_byte, next_next_byte], LS_LAST_2_BYTES | PS_LAST_2_BYTES)
257+
let next_two_bytes = output.get(idx + 1..idx + 3);
258+
if next_two_bytes != Some(&LS_LAST_2_BYTES[..])
259+
&& next_two_bytes != Some(&PS_LAST_2_BYTES[..])
260260
{
261261
last_line_is_ascii = false;
262+
// 3-byte Unicode char that isn't a line break.
263+
// We know it's 3 bytes, so we could do `idx += 3`, but that's more instruction bytes
264+
// than `idx += 1` (`inc` instruction). This branch is extremely rarely taken, and this
265+
// is in a hot loop, so it's better to optimize for the common case.
266+
// The remaining 2 bytes will hit the "Unicode char" branch below on next turns of the loop,
267+
// and they'll be skipped too.
262268
idx += 1;
263269
continue;
264270
}
@@ -268,6 +274,10 @@ impl<'a> SourcemapBuilder<'a> {
268274
_ => {
269275
// Unicode char
270276
last_line_is_ascii = false;
277+
// Note: Only increment `idx` by 1. We don't know how many bytes the char is, and non-ASCII
278+
// chars are rare, so it's not worthwhile adding more instructions to this hot loop to find out.
279+
// The remaining bytes of the char will hit this branch again on next turns of the loop,
280+
// and they'll be skipped too.
271281
idx += 1;
272282
continue;
273283
}

0 commit comments

Comments
 (0)