Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve performance, alternative approach (+149% throughput and more) #38

Merged
merged 2 commits into from Mar 24, 2023

Conversation

AlCalzone
Copy link
Contributor

@AlCalzone AlCalzone commented Mar 20, 2023

This PR is an alternative to #37

The idea is to first analyze the input string and turn it into an array of ANSI codes and characters. Slicing is then done by operating on the array. It basically rewrites the entire library, but yields a higher performance (+149% throughput, and more when reusing some of the work for slicing the same string multiple times). For my methodology on testing the performance, see #37. Some of the improvements are also taken from there.

I had to change two tests though - one unnecessarily used two separate foreground colors where the 2nd overwrote the 1st. And in another one, the expected string had the end codes in the same order as the start codes, while all others had it in the opposite order. I didn't see any difference when printing those strings.

  original:
    20 822 ops/s, ±1.70%
  
  (snip)

  other PR:
    41 278 ops/s, ±4.02%

  this PR:
    51 791 ops/s, ±2.93%

and if the result of the tokenization is memorized (export tokenize function, and add a copy of the sliceAnsi function which operates on a token array, instead of a string) , repeated slices on the same input (like in the test case) are much faster (+300% throughput):

  this PR, with reusing work:
    84 850 ops/s, ±3.21%

FYI, I have TypeScript code for this change. Let me know if that is preferred.

closes: #37

@AlCalzone AlCalzone changed the title perf: tokenize input and operate on analyzed array perf: tokenize input and operate on analyzed array (+149% throughput and more) Mar 20, 2023
t.is(sliceAnsi('\u001B[1m\u001B[48;2;255;255;255m\u001B[38;2;255;0;0municorn\u001B[39m\u001B[49m\u001B[22m', 0, 3), '\u001B[1m\u001B[48;2;255;255;255m\u001B[38;2;255;0;0muni\u001B[22m\u001B[49m\u001B[39m');
t.is(sliceAnsi('\u001B[1m\u001B[48;2;255;255;255m\u001B[38;2;255;0;0municorn\u001B[39m\u001B[49m\u001B[22m', 0, 3), '\u001B[1m\u001B[48;2;255;255;255m\u001B[38;2;255;0;0muni\u001B[39m\u001B[49m\u001B[22m');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after this change, the start codes get undone in the same order as in the input string.

t.is(JSON.stringify(sliceAnsi('\u001B[31m' + output, 0, 4)), JSON.stringify(`\u001B[31m${chalk.black.bgYellow(' RUN')}`));
t.is(JSON.stringify(sliceAnsi('\u001B[31m' + output, 0, 4)), JSON.stringify(chalk.black.bgYellow(' RUN')));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ANSI code for yellow is unnecessary in the output, because it immediately gets overwritten with black

@AlCalzone AlCalzone changed the title perf: tokenize input and operate on analyzed array (+149% throughput and more) improve performance, alternative approach (+149% throughput and more) Mar 20, 2023
@sindresorhus
Copy link
Member

I like this approach. Tokenizing it first makes a lot of sense.

index.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
@sindresorhus sindresorhus merged commit 29f76a4 into chalk:main Mar 24, 2023
2 checks passed
@sindresorhus
Copy link
Member

Thanks :)

@sindresorhus
Copy link
Member

https://github.com/chalk/slice-ansi/releases/tag/v6.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants