perf: add fast path for strings without ANSI codes#54
perf: add fast path for strings without ANSI codes#54sindresorhus merged 3 commits intochalk:mainfrom
Conversation
sindresorhus
left a comment
There was a problem hiding this comment.
Looks good.
I want to see the outcome of nodejs/node#61833 before merging this though.
75cabbe to
24dd1e0
Compare
|
nodejs/node#61833 was merged |
|
Can you include some benchmarks of large input, though? Like several megabytes. There are cases where people are running this on large log output from e.g. PTYs that have captured ANSI escapes. I worry they'll be hit with a performance regression by the introduction of two linear time scans, though given |
|
Benchmarked up to 5 MB with three scenarios on Apple M2 Max / Node 25.2.1 using mitata: Colored log output (ANSI throughout —
No regression. The Plain log output (no ANSI — fast path):
Worst case: ANSI only at end (
Even in the pathological worst case (5 MB of plain text with a single ANSI code at the very end), the double scan shows no measurable regression — |
|
LGTM then. :) Thank you for doing that. |
Problem
stripAnsialways runs a regex replacement, even when the input has no ANSI escape codes. This is the common case — most strings passed through strip-ansi are already plain text (e.g. checking/sanitizing user input, processing log lines that are mostly text).Changes
Adds a
string.includes('\x1B')guard before the regex. Since all ANSI escape sequences start with ESC (0x1B), its absence means no ANSI codes exist and we can return the string immediately — skipping regex compilation and allocation of a new string.Benchmarks
cpu: Apple M2 Max, runtime: node 25.2.1 (arm64-darwin)
"Hello, World!"(no ANSI)"a" × 1000(no ANSI)\x1B[31mHello\x1B[39m)Non-ANSI input is 13–46x faster. ANSI input has negligible overhead from the
includescheck (~5–10 ns).