chalk / wrap-ansi

Wordwrap a string with ANSI escape codes
MIT License
120 stars 25 forks source link

Performance - Drastically improve worst case regex performance #51

Closed adam-arthur closed 11 months ago

adam-arthur commented 1 year ago

Problem: Very poor performance when testing certain regexes due to unnecessary conversion to/from string/array.

Impact: Some of the reporters in Vitest that depend on this code are extremely slow. (See: https://github.com/vitest-dev/vitest/issues/2602)

Notes: While time complexity of both operations is theoretically the same, seems the VM is optimizing string specific operations much better than the conversion back/forth.

Future: In this case can run a single global regex on the entire string up front rather than re-allocating a new substring at each index. But for now this is simple and solves the issue.

adam-arthur commented 1 year ago

Please see for context: https://github.com/vitest-dev/vitest/issues/2602

Pasted Graphic isInsideEscape = false;
adam-arthur commented 1 year ago

CC @sindresorhus

adam-arthur commented 1 year ago

Updated PR to respect unicode character lengths

sindresorhus commented 1 year ago

Will add a test to this effect and update PR

Missing the test

moosemanf commented 1 year ago

I would argue the test is "missing" bc basically every other test confirms the correct behaviour, isn't it? @sindresorhus

gtm-nayan commented 1 year ago

My profiler shows me that a significant amount of time is also spent in the ansiRegex() call inside strip-ansi. stripAnsi is being called for every "word" and each time it creates a new regex object. Might want to looks there as well, creating the regex in the module scope and then resetting its lastIndex before each use sounds like a fairly low hanging fruit.

gtm-nayan commented 1 year ago

Completely tangential but @adam-arthur can you please tell me what tool you're using for the per-line timings in https://github.com/chalk/wrap-ansi/pull/51#issuecomment-1383810834 ?

sindresorhus commented 11 months ago

Bump :)