Skip to content

perf: fused normalization and input fact collection - #176

Merged
alyldas merged 1 commit into
mainfrom
perf/fuse-normalization-scan-facts
Jul 22, 2026
Merged

perf: fused normalization and input fact collection#176
alyldas merged 1 commit into
mainfrom
perf/fuse-normalization-scan-facts

Conversation

@alyldas

@alyldas alyldas commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fuse same-length normalization and loose candidate fact collection for full match iteration.
  • Preserve the measured strict-first compatibility path for boolean checks to avoid late strict-hit regressions.
  • Preserve both normalization strategies, exact UTF-16 positions, candidate ordering, taxonomy, and scanner behavior.
  • Add differential coverage for BMP, astral, fullwidth, case, homoglyph, zero-width, combining, and mixed inputs.
  • Keep public APIs unchanged.

Validation

  • npm ci
  • npm run check
  • npm run benchmark:profanity on origin/main and this branch with the same machine and command shape
  • Internal preparation microbenchmark with forced garbage collection

Benchmark Evidence

Baseline origin/main:

  • createProfanityFilter(): 7.6723 avg ms
  • check cyrillic clean: 0.0191 avg ms
  • check long clean: 0.9655 avg ms
  • check loose match: 0.0110 avg ms
  • check long late match: 0.2658 avg ms
  • scanner scan short match: 0.0150 avg ms
  • analyze short match: 0.0129 avg ms
  • censor short match: 0.0169 avg ms

This branch:

  • createProfanityFilter(): 7.0296 avg ms
  • check cyrillic clean: 0.0190 avg ms
  • check long clean: 0.9700 avg ms
  • check loose match: 0.0112 avg ms
  • check long late match: 0.2645 avg ms
  • scanner scan short match: 0.0137 avg ms
  • analyze short match: 0.0119 avg ms
  • censor short match: 0.0126 avg ms

Input preparation microbenchmark:

  • Separate reference path: 0.3096 avg ms; 15,121.6 retained bytes/input
  • Fused path: 0.2372 avg ms; 15,210.0 retained bytes/input

Fused preparation improves the measured preparation path by about 23% while retaining a flat output footprint. An eager-fused boolean prototype regressed check long late match from 0.2658 to 0.4204 avg ms, so check() intentionally retains strict-first separate facts after a miss.

Compatibility Notes

  • Public APIs, exports, scanner inputs, and normalization strategies are unchanged.
  • Normalized bytes, UTF-16 length and ranges, candidate bits and start positions, rule order, taxonomy, boundaries, scanner streaming, and runtime mutation snapshots remain compatible.
  • Boolean checks keep the measured strict-first compatibility path; analyze, censor, and full streaming use fused preparation.
  • Release Please PR chore(main): release 0.16.2 #175 remains open and is reserved for the single milestone release.

Closes #170

No publish, no merge, no tag/release.

@alyldas
alyldas merged commit 4b25b29 into main Jul 22, 2026
4 checks passed
@alyldas
alyldas deleted the perf/fuse-normalization-scan-facts branch July 22, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Fuse normalization and input fact collection into one UTF-16 pass

1 participant