Fast json stringify vs JSON stringify
sailingwithsandeep opened this issue · 3 comments
Prerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Fastify version
0
Plugin version
No response
Node.js version
20.11.1
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
13.0.1
Description
Why this result??
What i am doing wrong here???
Sorry for asking rookie question.
I am running this in pure Node.js No fastify, no expressjs.
Steps to Reproduce
import fastJson from 'fast-json-stringify';
const stringify = fastJson({
title: 'Example Schema',
type: 'object',
properties: {
firstName: {
type: 'string',
},
lastName: {
type: 'string',
},
age: {
description: 'Age in years',
type: 'integer',
},
reg: {
type: 'string',
},
},
});
setInterval(() => {
console.time('fast json stringify');
stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32,
reg: /"([^"]|\\")*"/,
});
console.timeEnd('fast json stringify');
console.time('normal json stringify');
JSON.stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32,
reg: /"([^"]|\\")*"/,
});
console.timeEnd('normal json stringify');
}, 1000);
Expected Behavior
No response
Good spot. There is a difference in how we render regexp:
import fastJson from './index.js';
const stringify = fastJson({
title: 'Example Schema',
type: 'object',
properties: {
firstName: {
type: 'string',
},
lastName: {
type: 'string',
},
age: {
description: 'Age in years',
type: 'integer',
},
reg: {
type: 'string',
},
},
});
console.log(stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32,
reg: /"([^"]|\\")*"/,
}))t
console.log(JSON.stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32,
reg: /"([^"]|\\")*"/,
}))
As you can see the output is different:
{"firstName":"Matteo","lastName":"Collina","age":32,"reg":"\"([^\"]|\\\\\")*\""}
{"firstName":"Matteo","lastName":"Collina","age":32,"reg":{}}
The former takes more time to compute. Note that you are telling fjs you want a string, and it's coercing the regexp into it. Instead, JSON.stringify()
returns an empty object. It's not a fair comparison.
Note that if you want to benchmark this you should run it in a tight loop, otherwise none of the optimizations will kick in - if you never call fjs, it won't get faster. Here is a good way to benchmark:
import fastJson from './index.js';
const stringify = fastJson({
title: 'Example Schema',
type: 'object',
properties: {
firstName: {
type: 'string',
},
lastName: {
type: 'string',
},
age: {
description: 'Age in years',
type: 'integer',
},
reg: {
type: 'string',
},
},
});
console.time('fast-json-stringify');
for (let i = 0; i < 1000000; i++) {
stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32
})
}
console.timeEnd('fast-json-stringify');
console.time('JSON.stringify');
for (let i = 0; i < 1000000; i++) {
JSON.stringify({
firstName: 'Matteo',
lastName: 'Collina',
age: 32
})
}
console.timeEnd('JSON.stringify');
Thanks for the heads up.
Also, after running it for a while (maybe because of memorization?), I got the improved result from my benchmark as well.
Anyways, Sorry for being skeptical here!!!
Yes, I think optimizer kicks in when the serializer gets warm.
I checked it on container and observed that it is ~3x-4x faster than JSON.stringify after some times.
Although JSON.stringify seems faster initially.