util: add fast path to stripVTControlCharacters#61833
util: add fast path to stripVTControlCharacters#61833privatenumber wants to merge 3 commits intonodejs:mainfrom
Conversation
|
Review requested:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #61833 +/- ##
==========================================
+ Coverage 89.72% 89.73% +0.01%
==========================================
Files 675 675
Lines 204797 204801 +4
Branches 39344 39348 +4
==========================================
+ Hits 183752 183788 +36
+ Misses 13324 13282 -42
- Partials 7721 7731 +10
🚀 New features to boost your workflow:
|
addaleax
left a comment
There was a problem hiding this comment.
Can you leave a comment in the source about why this short-circuiting is added? Because it still "looks" redundant when just reading the source.
| if (!StringPrototypeIncludes(str, '\u001B') && | ||
| !StringPrototypeIncludes(str, '\u009B')) | ||
| return str; |
There was a problem hiding this comment.
You are doing two passes here, why not use a simple regex here that only checks these 2 characters in one pass?
| if (!StringPrototypeIncludes(str, '\u001B') && | |
| !StringPrototypeIncludes(str, '\u009B')) | |
| return str; | |
| if (!RegExpPrototypeTest(/[\u001B\u009B]/, str)) | |
| return str; |
Did you test the performance of this? I think this would be even faster
There was a problem hiding this comment.
It's unlikely that a Regex test will be faster.
Possibly this is better:
if (StringPrototypeIndexOf(str, '\u001B') === -1 &&
StringPrototypeIndexOf(str, '\u009B') === -1)
RafaelGSS
left a comment
There was a problem hiding this comment.
Please, share nodejs benchmark results. The one you attached in the PR description doesn't seem Node.js one.
| if (!StringPrototypeIncludes(str, '\u001B') && | ||
| !StringPrototypeIncludes(str, '\u009B')) | ||
| return str; |
There was a problem hiding this comment.
It's unlikely that a Regex test will be faster.
Possibly this is better:
if (StringPrototypeIndexOf(str, '\u001B') === -1 &&
StringPrototypeIndexOf(str, '\u009B') === -1)
Problem
stripVTControlCharactersalways runs a regex replacement, even when the input contains no ANSI escape codes. This is the common case — most strings passed through are already plain text (e.g. checking/sanitizing user input, processing log lines that are mostly text).Changes
Adds a
StringPrototypeIncludesguard for ESC (\u001B) and CSI (\u009B) before the regex. Since all ANSI escape sequences start with one of these introducers, their absence means no ANSI codes exist and we can return the string immediately — skipping regex execution.Based on the same optimization proposed in chalk/strip-ansi#54.
Also adds a benchmark and test coverage for the fast path, 7-bit ESC sequences, and 8-bit CSI sequences.
Benchmarks
cpu: Apple M2 Max, runtime: node v23.11.0 (arm64-darwin)
Isolated component test showing speedup scaling with string length for non-ANSI input:
ANSI input has negligible overhead from the
includescheck.