From 4f92188b58ed9c90f12ba6b3d747e44e0406836d Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Tue, 24 Oct 2023 22:58:04 +0200 Subject: [PATCH] chore: update benchmarks --- BENCH.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ README.md | 46 ++-------------------------------------------- bench.mjs | 16 ++++++++++------ 3 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 BENCH.md diff --git a/BENCH.md b/BENCH.md new file mode 100644 index 0000000..c49785e --- /dev/null +++ b/BENCH.md @@ -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) diff --git a/README.md b/README.md index 16ea3f8..904c088 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/bench.mjs b/bench.mjs index 183731b..bea6913 100644 --- a/bench.mjs +++ b/bench.mjs @@ -45,7 +45,7 @@ function benchTryCatch(name, val) { suite.add("JSON.parse (try-catch)", () => { try { JSON.parse(val); - } catch (err) { + } catch { return val; } }); @@ -58,7 +58,7 @@ function benchTryCatch(name, val) { suite.add("sjson (try-catch)", () => { try { sjson.parse(val); - } catch (err) { + } catch { return val; } }); @@ -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)));