fastify/fast-json-stringify

Worse performance with response schema when 'const' keyword is used

DanieleFedeli opened this issue · 6 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

4.3.0

Plugin version

No response

Node.js version

16.13.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.0

Description

When specifying the response schema with 'const' I noticed that the RPS decreased.

Steps to Reproduce

Options used:

{
  schema: {
    response: {
        200: {
          type: "object",
          properties: {
            msg: { type: "string" },
          }
      }
   }
}

Schema benchmark:
Screenshot 2022-08-07 alle 12 06 23

Options used:

{
  schema: {
    response: {
        200: {
          type: "object",
          properties: {
            msg: { const: "hello world" },
          }
      }
   }
}

Schema with const:
Screenshot 2022-08-07 alle 12 08 13

Repository with the code: https://github.com/DanieleFedeli/fastify-response-schema-issue

Expected Behavior

I expect at least the same performance when specifying const in the schema.

Very interesting! This looks like a bug in fast-json-stringify. I'll move the bug there.

How is the performance if we also use type: "string" or if we use enum instead of const?

With type string

{
  type: "object",
  properties: {
    msg: { type: "string", const: "hello world" },
  }
}

Screenshot 2022-08-07 alle 16 18 25

With enum

{
  type: "object",
  properties: {
    msg: { enum: ["hello world"] },
  }
}

Screenshot 2022-08-07 alle 16 20 00

It improves drastically

I would say it is expected.
When the type is not defined and const is exist, FJS need to guess whether the content is meet the schema or not.
So, it went through ajv for the guessing and it is expected to be slow in this case.

code += `
if(ajv.validate(${JSON.stringify(schema)}, ${input}))
json += '${JSON.stringify(schema.const)}'
else
throw new Error(\`Item $\{JSON.stringify(${input})} does not match schema definition.\`)
`

But i can determine the type of const before i use it in ajv. So do we have to improve the docs or should we write a function which traverses the entries for const and determines the corresponding type?

+1 to mention it in the docs and open a new fresh issue to optimize it as we can.