From 594843af5081b9c9d14c2cc26100cfe9d4c110f4 Mon Sep 17 00:00:00 2001 From: Adam Eisenreich Date: Fri, 27 Oct 2023 23:50:23 +0200 Subject: [PATCH] feat: Add native JSON to benchmark --- benchmark/index.js | 15 ++++++++- benchmark/native-json/index.js | 2 ++ benchmark/native-json/parser.js | 33 ++++++++++++++++++++ benchmark/native-json/stringify.js | 50 ++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 benchmark/native-json/index.js create mode 100644 benchmark/native-json/parser.js create mode 100644 benchmark/native-json/stringify.js diff --git a/benchmark/index.js b/benchmark/index.js index 5c20cbb..38bae45 100644 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -7,11 +7,13 @@ import * as superjson from "superjson"; import { createTson, tsonDate, tsonRegExp, tsonSet } from "tupleson"; import { gzipSync } from "zlib"; +import { nativeJSONParse, nativeJSONStringify } from './native-json/index.js'; + const obj = { array: [{ foo: 1 }, { bar: 2 }, { baz: 3 }], date: new Date(), number: 42, - regex: /the quick brown fox/, + regex: /the quick brown fox/i, set: new Set([1, 2, 3]), xss: '', }; @@ -25,6 +27,17 @@ const tson = createTson({ }); const testingMethods = [ + { + name: 'native', + parse: str => nativeJSONParse(str), + results: { + parse: 0, + size: 0, + sizeGZipped: 0, + stringify: 0, + }, + stringify: () => nativeJSONStringify(obj), + }, { name: 'superJSON', parse: str => superjson.parse(str), diff --git a/benchmark/native-json/index.js b/benchmark/native-json/index.js new file mode 100644 index 0000000..383a6f9 --- /dev/null +++ b/benchmark/native-json/index.js @@ -0,0 +1,2 @@ +export * from './stringify.js'; +export * from './parser.js'; diff --git a/benchmark/native-json/parser.js b/benchmark/native-json/parser.js new file mode 100644 index 0000000..a45c01e --- /dev/null +++ b/benchmark/native-json/parser.js @@ -0,0 +1,33 @@ +export function nativeJSONParse(value) { + return JSON.parse(value, reviver); +} + +function dateReviver(value) { + return new Date(value.iso); +} + +function regExpReviver(value) { + return new RegExp(value.source, value.flags); +} + +function setReviver(value) { + return new Set(value.values); +} + +function reviver(key, value) { + if (typeof value === 'object' && value !== null) { + if ('__type' in value) { + switch (value.__type) { + case 'Date': + return dateReviver(value); + case 'RegExp': + return regExpReviver(value); + case 'Set': + return setReviver(value); + } + } + } + + // For primitives, use native function + return value; +} diff --git a/benchmark/native-json/stringify.js b/benchmark/native-json/stringify.js new file mode 100644 index 0000000..6d61009 --- /dev/null +++ b/benchmark/native-json/stringify.js @@ -0,0 +1,50 @@ +export function nativeJSONStringify(value) { + return JSON.stringify(value, replacer); +} + +function dateReplacer(value) { + return { + __type: 'Date', + iso: value.toISOString(), + }; +} + +function regExpReplacer(value) { + return { + __type: 'RegExp', + flags: value.flags, + source: value.source, + }; +} + +function setReplacer(value) { + return { + __type: 'Set', + values: Array.from(value), + }; +} + +function replacer(key, value) { + if (typeof value === 'bigint') { + return value.toString(); + } else if (typeof value === 'symbol') { + return value.toString(); + } else if (typeof value === 'object') { + if (value instanceof Date) { + return dateReplacer(value); + } else if (value instanceof RegExp) { + return regExpReplacer(value); + } else if (value instanceof Set) { + return setReplacer(value); + } + + return value; + } else if (typeof value === 'string') { + if (this[key] instanceof Date) { + return dateReplacer(this[key]); + } + } + + // For primitives, use native function + return value; +}