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

perf: speed up stringify_string #65

Merged
merged 3 commits into from
May 14, 2023

Conversation

gtm-nayan
Copy link
Contributor

@gtm-nayan gtm-nayan commented May 14, 2023

A string is a sequence of Unicode code points wrapped with quotation marks (U+0022). All code points may be placed within the quotation marks except for the code points that must be escaped: quotation mark (U+0022), reverse solidus (U+005C), and the control characters U+0000 to U+001F.

According to the JSON spec, anything except "\ and the control characters can go in the string, the only characters we want to escape in addition would be <, \u2028 and \u2029 for HTML embedding (unless I'm missing something).

Instead of building up strings character by,

  1. this adds a fast path for just returning the original string wrapped by quotes if there are no characters to be escaped
  2. If there are any to be escaped, it'll copy chunks of the string at once

and the object key hashmap key seems to be 25% ish slower than the switch version, this does introduce some duplication but it should only be on the server side, will try to consolidate both at some point.

Results:

Running "circular-dedupe to string" suite...
    97 562 ops/s, ±0.54%    | slowest, 39.26% slower
    160 633 ops/s, ±0.13%   | fastest
Running "circular-simple to string" suite...
    401 480 ops/s, ±0.22%   | slowest, 36.8% slower
    635 267 ops/s, ±0.17%   | fastest
Running "dedupe-object to string" suite...
    194 025 ops/s, ±0.28%   | slowest, 39.8% slower
    322 282 ops/s, ±0.12%   | fastest
Running "large-circular-collection to string" suite...
    571 ops/s, ±0.37%     | slowest, 54.32% slower
    1 250 ops/s, ±0.38%   | fastest
Running "large-complex-collection to string" suite...
    2 481 ops/s, ±0.19%   | slowest, 64.81% slower
    7 050 ops/s, ±0.11%   | fastest
Running "large-dedupe-collection to string" suite...
    611 ops/s, ±0.43%     | slowest, 52.49% slower
    1 286 ops/s, ±0.18%   | fastest
Running "large-invalid-keys-collection to string" suite...
    169 ops/s, ±0.41%   | slowest, 51.85% slower
    351 ops/s, ±2.11%   | fastest
Running "large-simple-collection to string" suite...
    160 ops/s, ±0.98%   | slowest, 53.35% slower
    343 ops/s, ±0.61%   | fastest
Running "simple-object to string" suite...
    826 857 ops/s, ±0.55%     | slowest, 27.49% slower
    1 140 336 ops/s, ±0.24%   | fastest
Running "small-collection to string" suite...
    59 066 ops/s, ±0.23%    | slowest, 54.59% slower
    130 076 ops/s, ±0.30%   | fastest

I modified the seroval benchmark to compare stringify/parse results instead of uneval/eval and sprinkled in some control characters in some of the strings. The first line in each is the previous version, and the second line is with this PR.

@Rich-Harris Rich-Harris merged commit c8239e4 into Rich-Harris:master May 14, 2023
1 check passed
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