Skip to content

Commit 542a3dd

Browse files
committed
benchmark: create http benchmark
1 parent 798ce66 commit 542a3dd

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

benchmark/http/json-parsing.js

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const http = require('http');
5+
6+
const configs = {
7+
small: {
8+
json: JSON.stringify({
9+
id: 1,
10+
name: 'Alice',
11+
active: true,
12+
score: 9.5,
13+
}),
14+
schema: {
15+
type: 'object',
16+
properties: {
17+
id: { type: 'integer' },
18+
name: { type: 'string' },
19+
active: { type: 'boolean' },
20+
score: { type: 'number' },
21+
},
22+
},
23+
},
24+
medium: {
25+
json: JSON.stringify({
26+
order_id: 'ORD-12345',
27+
created_at: '2024-01-01T00:00:00Z',
28+
status: 'pending',
29+
total: 109.97,
30+
currency: 'USD',
31+
user: { id: 1, name: 'Alice', email: 'alice@example.com' },
32+
items: [
33+
{ product_id: 'P1', name: 'Widget', quantity: 2, price: 29.99, sku: 'WGT-001' },
34+
{ product_id: 'P2', name: 'Gadget', quantity: 1, price: 49.99, sku: 'GDG-001' },
35+
],
36+
shipping_address: {
37+
street: '123 Main St',
38+
city: 'Anytown',
39+
state: 'CA',
40+
zip: '12345',
41+
country: 'US',
42+
},
43+
}),
44+
schema: {
45+
type: 'object',
46+
properties: {
47+
order_id: { type: 'string' },
48+
status: { type: 'string' },
49+
total: { type: 'number' },
50+
items: {
51+
type: 'array',
52+
items: {
53+
type: 'object',
54+
properties: {
55+
product_id: { type: 'string' },
56+
quantity: { type: 'integer' },
57+
price: { type: 'number' },
58+
},
59+
},
60+
},
61+
},
62+
},
63+
},
64+
large: {
65+
json: JSON.stringify({
66+
id: 'usr_abc123',
67+
username: 'alice_wonder',
68+
email: 'alice@example.com',
69+
full_name: 'Alice Wonderland',
70+
created_at: '2020-01-01T00:00:00Z',
71+
updated_at: '2024-06-15T12:30:00Z',
72+
last_login: '2024-06-20T08:00:00Z',
73+
is_active: true,
74+
is_verified: true,
75+
role: 'admin',
76+
plan: 'enterprise',
77+
preferences: {
78+
theme: 'dark',
79+
language: 'en',
80+
notifications: { email: true, sms: false, push: true },
81+
timezone: 'America/New_York',
82+
date_format: 'MM/DD/YYYY',
83+
},
84+
profile: {
85+
bio: 'Software Engineer',
86+
website: 'https://example.com',
87+
avatar_url: 'https://cdn.example.com/avatars/alice.jpg',
88+
location: 'New York, NY',
89+
company: 'Acme Corp',
90+
job_title: 'Senior Engineer',
91+
phone: '+1-555-0100',
92+
},
93+
stats: {
94+
total_orders: 42,
95+
total_spent: 1234.56,
96+
loyalty_points: 9876,
97+
reviews_count: 15,
98+
avg_rating: 4.8,
99+
},
100+
tags: ['vip', 'early-adopter', 'beta-tester'],
101+
addresses: [
102+
{
103+
id: 'addr_1',
104+
type: 'billing',
105+
street: '123 Main St',
106+
city: 'New York',
107+
state: 'NY',
108+
zip: '10001',
109+
country: 'US',
110+
is_default: true,
111+
},
112+
{
113+
id: 'addr_2',
114+
type: 'shipping',
115+
street: '456 Oak Ave',
116+
city: 'Brooklyn',
117+
state: 'NY',
118+
zip: '11201',
119+
country: 'US',
120+
is_default: false,
121+
},
122+
],
123+
payment_methods: [
124+
{ id: 'pm_1', type: 'credit_card', last4: '4242', brand: 'Visa', exp_month: 12, exp_year: 2027 },
125+
{ id: 'pm_2', type: 'paypal', email: 'alice@paypal.com' },
126+
],
127+
}),
128+
schema: {
129+
type: 'object',
130+
properties: {
131+
id: { type: 'string' },
132+
username: { type: 'string' },
133+
email: { type: 'string' },
134+
is_active: { type: 'boolean' },
135+
role: { type: 'string' },
136+
},
137+
},
138+
},
139+
};
140+
141+
const bench = common.createBenchmark(main, {
142+
method: ['node', 'v8', 'ajv'],
143+
payload: Object.keys(configs),
144+
connections: [100, 500],
145+
duration: 5,
146+
});
147+
148+
function main({ method, payload, connections, duration }) {
149+
const { json, schema } = configs[payload];
150+
151+
let parser;
152+
let validate;
153+
if (method === 'node') {
154+
const { Parser } = require('node:json');
155+
parser = new Parser(schema);
156+
parser.parse(json); // Warm up before accepting connections.
157+
} else if (method === 'ajv') {
158+
const Ajv = require('ajv');
159+
const ajv = new Ajv();
160+
validate = ajv.compile(schema);
161+
validate(JSON.parse(json)); // Warm up before accepting connections.
162+
}
163+
164+
const response = Buffer.from('{"ok":true}');
165+
166+
const server = http.createServer((_req, res) => {
167+
if (method === 'node') {
168+
parser.parse(json);
169+
} else if (method === 'ajv') {
170+
validate(JSON.parse(json));
171+
} else {
172+
JSON.parse(json);
173+
}
174+
175+
res.writeHead(200, {
176+
'Content-Type': 'application/json',
177+
'Content-Length': response.length,
178+
});
179+
res.end(response);
180+
});
181+
182+
server.listen(0, () => {
183+
bench.http({
184+
path: '/',
185+
connections,
186+
duration,
187+
port: server.address().port,
188+
}, () => {
189+
server.close();
190+
});
191+
});
192+
}

0 commit comments

Comments
 (0)