fastify/fast-json-stringify

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.

image

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.