Skip to content

Commit

Permalink
chore: update benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Oct 24, 2023
1 parent 4dbb707 commit 4f92188
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 50 deletions.
47 changes: 47 additions & 0 deletions BENCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
=== Non-string fallback ==
JSON.parse x 9,795,965 ops/sec ±1.05% (99 runs sampled)
destr x 251,242,150 ops/sec ±0.16% (97 runs sampled)
safeDestr x 71,403,846 ops/sec ±0.30% (98 runs sampled)
sjson:
@hapi/bourne x 9,398,223 ops/sec ±0.20% (94 runs sampled)
Fastest is destr

=== Known values ==
JSON.parse x 24,819,945 ops/sec ±0.67% (98 runs sampled)
destr x 64,177,771 ops/sec ±0.23% (98 runs sampled)
safeDestr x 35,102,427 ops/sec ±0.50% (95 runs sampled)
sjson x 13,214,663 ops/sec ±1.16% (96 runs sampled)
@hapi/bourne x 22,661,470 ops/sec ±0.38% (100 runs sampled)
Fastest is destr

=== plain string (short) ==
JSON.parse (try-catch) x 13,619,068 ops/sec ±0.96% (95 runs sampled)
destr x 69,967,512 ops/sec ±0.45% (95 runs sampled)
safeDestr x 36,915,513 ops/sec ±2.45% (92 runs sampled)
sjson (try-catch) x 9,223,733 ops/sec ±0.31% (98 runs sampled)
@hapi/bourne x 12,190,344 ops/sec ±0.80% (94 runs sampled)
Fastest is destr

=== plain string (long) ==
JSON.parse (try-catch) x 153,349 ops/sec ±0.55% (99 runs sampled)
destr x 36,427,741 ops/sec ±0.34% (97 runs sampled)
safeDestr:
sjson (try-catch) x 325,713 ops/sec ±0.88% (93 runs sampled)
@hapi/bourne:
Fastest is destr

=== package.json ==
JSON.parse x 324,505 ops/sec ±0.12% (94 runs sampled)
destr x 274,520 ops/sec ±0.15% (97 runs sampled)
safeDestr x 271,451 ops/sec ±0.16% (95 runs sampled)
sjson x 264,515 ops/sec ±1.73% (93 runs sampled)
@hapi/bourne x 294,835 ops/sec ±0.19% (97 runs sampled)
Fastest is JSON.parse

=== broken object ==
JSON.parse (try-catch) x 99,745 ops/sec ±0.53% (96 runs sampled)
destr x 86,757 ops/sec ±0.55% (98 runs sampled)
safeDestr:
sjson (try-catch) x 154,320 ops/sec ±0.37% (97 runs sampled)
@hapi/bourne:
Fastest is sjson (try-catch)
46 changes: 2 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,51 +118,9 @@ safeDestr("[foo");

## Benchmarks

Locally try with `pnpm benchmark`. Below are results on Node.js **v20.5.0** with MBA M2.
`destr` is sometimes little bit slower than `JSON.parse` when parsing a valid JSON string mainly because of transform to avoid [prototype pollution](https://learn.snyk.io/lessons/prototype-pollution/javascript/) which can lead to serious security issues if not being sanitized. In the other words, `destr` is better when input is not always a JSON string or from untrusted source like request body.

**Note** `destr` is sometimes little bit slower than `JSON.parse` when parsing a valid JSON string mainly because of transform to avoid [prototype pollution](https://learn.snyk.io/lessons/prototype-pollution/javascript/) which can lead to serious security issues if not being sanitized. In the other words, `destr` is better when input is not always a JSON string or from untrusted source like request body.

```
=== Non-string fallback ==
JSON.parse x 9,506,702 ops/sec ±1.68% (92 runs sampled)
destr x 159,565,446 ops/sec ±0.24% (98 runs sampled)
safeDestr x 73,624,106 ops/sec ±0.39% (95 runs sampled)
sjson:
@hapi/bourne x 9,404,463 ops/sec ±0.62% (96 runs sampled)
Fastest is destr
=== Known values ==
JSON.parse x 15,000,474 ops/sec ±0.82% (93 runs sampled)
destr x 96,977,026 ops/sec ±0.13% (101 runs sampled)
safeDestr x 47,618,310 ops/sec ±0.15% (98 runs sampled)
sjson x 11,176,069 ops/sec ±0.47% (93 runs sampled)
@hapi/bourne x 14,650,782 ops/sec ±0.64% (93 runs sampled)
Fastest is destr
=== plain string ==
JSON.parse (try-catch) x 11,775,641 ops/sec ±0.64% (95 runs sampled)
destr x 111,118,106 ops/sec ±0.53% (101 runs sampled)
safeDestr x 52,455,654 ops/sec ±0.21% (97 runs sampled)
sjson (try-catch) x 9,282,956 ops/sec ±0.47% (96 runs sampled)
@hapi/bourne x 11,547,144 ops/sec ±0.68% (96 runs sampled)
Fastest is destr
=== package.json ==
JSON.parse x 420,496 ops/sec ±0.20% (98 runs sampled)
destr x 358,257 ops/sec ±0.58% (98 runs sampled)
safeDestr x 351,278 ops/sec ±1.10% (98 runs sampled)
sjson x 358,003 ops/sec ±0.14% (102 runs sampled)
@hapi/bourne x 398,852 ops/sec ±0.32% (99 runs sampled)
Fastest is JSON.parse
=== broken object ==
JSON.parse (try-catch) x 137,788 ops/sec ±0.68% (98 runs sampled)
destr x 111,878 ops/sec ±0.50% (98 runs sampled)
safeDestr:
sjson (try-catch) x 219,924 ops/sec ±0.62% (98 runs sampled)
@hapi/bourne:
Fastest is sjson (try-catch)
```
Check [Benchmarks](./BENCH.md)

## License

Expand Down
16 changes: 10 additions & 6 deletions bench.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function benchTryCatch(name, val) {
suite.add("JSON.parse (try-catch)", () => {
try {
JSON.parse(val);
} catch (err) {
} catch {
return val;
}
});
Expand All @@ -58,7 +58,7 @@ function benchTryCatch(name, val) {
suite.add("sjson (try-catch)", () => {
try {
sjson.parse(val);
} catch (err) {
} catch {
return val;
}
});
Expand All @@ -68,10 +68,14 @@ function benchTryCatch(name, val) {
suite.run();
}

bench("Non-string fallback", 3.14159265359);
bench("Non-string fallback", 3.141_592_653_59);
bench("Known values", "true");
benchTryCatch("plain string", `"SALAM"`);

const pkg = fs.readFileSync("./package.json", "utf-8");
benchTryCatch("plain string (short)", `"SALAM"`);

const longStr = fs.readFileSync("./pnpm-lock.yaml", "utf8");
benchTryCatch("plain string (long)", longStr);

const pkg = fs.readFileSync("./package.json", "utf8");
bench("package.json", pkg);
benchTryCatch("broken object", pkg.substring(0, pkg.length - 1));
benchTryCatch("broken object", pkg.slice(0, Math.max(0, pkg.length - 1)));

0 comments on commit 4f92188

Please sign in to comment.