Skip to content

Commit 99df5b9

Browse files
committed
src: create schema-baed parser
1 parent 6b5178f commit 99df5b9

File tree

8 files changed

+1069
-0
lines changed

8 files changed

+1069
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const assert = require('assert');
5+
const { Parser } = require('node:json');
6+
7+
const payloads = {
8+
flat_small: {
9+
json: '{"name":"Alice","age":30,"active":true,"score":9.5}',
10+
schema: {
11+
type: 'object',
12+
properties: {
13+
name: { type: 'string' },
14+
age: { type: 'integer' },
15+
active: { type: 'boolean' },
16+
score: { type: 'number' },
17+
},
18+
},
19+
},
20+
flat_large: {
21+
json: JSON.stringify({
22+
id: 1, name: 'Bob', email: 'bob@example.com', age: 25,
23+
address: '123 Main St', city: 'Anytown', state: 'NY', zip: '10001',
24+
country: 'US', phone: '555-1234', fax: '555-5678', website: 'http://example.com',
25+
company: 'Acme', department: 'Engineering', title: 'Engineer',
26+
manager: 'Carol', team: 'Backend', score: 8.2, active: true, tags: 'foo,bar',
27+
}),
28+
schema: {
29+
type: 'object',
30+
properties: {
31+
id: { type: 'integer' },
32+
name: { type: 'string' },
33+
score: { type: 'number' },
34+
active: { type: 'boolean' },
35+
},
36+
},
37+
},
38+
nested: {
39+
json: '{"user":{"id":42,"name":"Carol","roles":["admin","user"]},"meta":{"version":2,"debug":false}}',
40+
schema: {
41+
type: 'object',
42+
properties: {
43+
user: {
44+
type: 'object',
45+
properties: {
46+
id: { type: 'integer' },
47+
name: { type: 'string' },
48+
},
49+
},
50+
},
51+
},
52+
},
53+
array: {
54+
json: JSON.stringify(
55+
Array.from({ length: 10 }, (_, i) => ({
56+
id: i + 1, name: `Item ${i + 1}`, value: i * 1.5, active: i % 2 === 0,
57+
description: `Description for item ${i + 1}`, extra: 'ignored',
58+
})),
59+
),
60+
schema: {
61+
type: 'array',
62+
items: {
63+
type: 'object',
64+
properties: {
65+
id: { type: 'integer' },
66+
name: { type: 'string' },
67+
value: { type: 'number' },
68+
active: { type: 'boolean' },
69+
},
70+
},
71+
},
72+
},
73+
};
74+
75+
const bench = common.createBenchmark(main, {
76+
method: ['node', 'v8'],
77+
payload: Object.keys(payloads),
78+
n: [1e4],
79+
});
80+
81+
function main({ method, payload, n }) {
82+
const { json, schema } = payloads[payload];
83+
84+
if (method === 'node') {
85+
const parser = new Parser(schema);
86+
let result = parser.parse(json); // Warm up / avoid dead code elimination
87+
bench.start();
88+
for (let i = 0; i < n; ++i) {
89+
result = parser.parse(json);
90+
}
91+
bench.end(n);
92+
assert.ok(result);
93+
} else {
94+
let result = JSON.parse(json);
95+
bench.start();
96+
for (let i = 0; i < n; ++i) {
97+
result = JSON.parse(json);
98+
}
99+
bench.end(n);
100+
assert.ok(result);
101+
}
102+
}

β€Žlib/internal/bootstrap/realm.jsβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ const legacyWrapperList = new SafeSet([
124124
// beginning with "internal/".
125125
// Modules that can only be imported via the node: scheme.
126126
const schemelessBlockList = new SafeSet([
127+
'json',
127128
'sea',
128129
'sqlite',
129130
'quic',

β€Žlib/json.jsβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
const { Parser } = internalBinding('json_parser');
4+
5+
module.exports = { Parser };

β€Žnode.gypβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
'src/node_file.cc',
128128
'src/node_file_utils.cc',
129129
'src/node_http_parser.cc',
130+
'src/node_json_parser.cc',
130131
'src/node_http2.cc',
131132
'src/node_i18n.cc',
132133
'src/node_locks.cc',

β€Žsrc/node_binding.ccβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
V(internal_only_v8) \
6161
V(js_stream) \
6262
V(js_udp_wrap) \
63+
V(json_parser) \
6364
V(locks) \
6465
V(messaging) \
6566
V(modules) \

0 commit comments

Comments
Β (0)