DEV Community

Cover image for Bun is up to 20x slower than NodeJS in logic operations
Jeongho Nam
Jeongho Nam

Posted on

Bun is up to 20x slower than NodeJS in logic operations

Preface

NodeJS vs Bun: typia.is<T>() function benchmark

typia is a transformer library supporting superfast runtime validation, and JSON serialization function boosting up performance by AoT (Ahead of Time) optimization skill. For example, its validation speed is 20,000x faster than class-validator, and JSON serialization is 20x faster than class-transformer.

By the way, after the Bun has come to JS world, there had been many reports that typia is not fast in the Bun runtime. There even had been a report that typia's JSON serialization is slower than the native JSON.stringify() function in the Bun environment.

However, as I was busy in due to supporting the A.I. chatbot development feature, I could not respond to such Bun performance issues for a long time. Since all of typia's functions are working properly in Bun, I thought that I could put aside performance issues as a priority, but six months passed by in the blink of an eye.

Fortunately, I could finish the A.I. chatbot feature development in recent, so that I could develop the Bun performance benchmark program at now. And as Bun has always emphasized its lightweight and fast performance, the extreme slowness in typia validation and JSON serialization logics surprised me a lot.

Oh my god, Bun is maximum 20x slower than NodeJS in the typia.is<T>() function.

typia.is<T>() function benchmark

//----
// TypeScript Source Code
//----
import typia from "typia";

typia.is<string>("Hello World");

//----
// Compiled JavaScript Code
//----
(() => {
  return (input) => "string" === typeof input;
})()("Hello World");
Enter fullscreen mode Exit fullscreen mode

typia.is<T>() is a transformer function that generating type checking code whether the parameteric input value is following the type T or not. If the input value is following the type T, it returns true. Otherwise input is different with the type T, it returns false.

Because typia.is<T>() generates dedicated type checking code only for the type T, its validation speed is stable and faster than any other libraries. Such compilation level dedicated optimization skill is called AoT (Ahead of Time) compilation. When AoT compilation stategy is used, NodeJS v8 engine performs hidden class optimization for maximize the performance.

is() function benchmark on NodeJS

typia.is<T>() function benchmark on NodeJS

It is the secret of the typia's superfast validation speed. In the NodeJS environment, typia's validation speed (in NodeJS) is maxmum 20,000x faster than class-validator which does not have any optimization strategy. Besides, typebox performs the JIT (Just in Time) compilation strategy, and as it can take advantage of the v8 engine's hidden class optimization, it can compete speed with typia.

However, in the Bun, such AoT (Ahead of Time) or JIT (Just in Time) compilation strategy seems not working at all. I guess that Bun does not perform hidden class optimization skill, or there is a critical problem on the Bun's hidden class optimization like algorithm, and it is the reason why Bun is maximum 20x slower than NodeJS in the typia.is<T>() function.

Reference: typia's hidden optimization of v8 engine

NodeJS vs Bun: typia.is<T>() function benchmark

typia.json.stringify<T>() function benchmark

//----
// TypeScript Source Code
//----
import typia from "typia";

interface Member {
  name: string;
  age: number;
}
typia.json.stringify<Member>({
  email: "John Doe",
  age: 24,
});

//----
// Compiler JavaScript Code
//----
import * as __typia_transform__jsonStringifyString from "typia/lib/internal/_jsonStringifyString.js";
(() => {
  const _so0 = (input) =>
    `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"age":${input.age}}`;
  return (input) => _so0(input);
})()({
  email: "John Doe",
  age: 24,
});
Enter fullscreen mode Exit fullscreen mode

typia.json.stringify<T>() is a transformer function that is similar with JSON.stringify() function, but working only for the type T. As the typia.json.stringify<T>() function aims only for the type T with the AoT (Ahead of Time) compilation skill, its JSON serialization is faster than the native JSON.stringify() function.

Because of the AoT compilation of typia and NodeJS v8 engine's hidden class optimization skills, typia.json.stringify<T>() is maximum 20x faster than class-transformer in the NodeJS environment, and maximum 16x faster than the native JSON.stringify() function.

 raw `typia.json.stringify<T>()` endraw  function benchmark in NodeJS

typia.json.stringify<T>() function benchmark in NodeJS

However, in the Bun environment, typia.json.stringify<T>() function's JSON serialization speed becomes slower, even sometimes worse than the native JSON.stringify() function. This is the reason why I suspect that AoT compilation skill doesn't work at all on the Bun environment.

If the AoT compilation and v8 hidden class optimization skill worked, typia.json.stringify<T>() function cannot be slower than the native JSON.stringify() function in the theoretical level. How dedicated code only for the type T can be slower than the general JSON.stringify() function accessing to the properties dynamically?

I think that Bun does not perform hidden class optimization skill, or there is a critical problem on the Bun's hidden class optimization like algorithm.

 raw `typia.json.stringify<T>()` endraw  function benchmark in Bun

typia.json.stringify<T>() function benchmark in Bun

Skyblue is JSON.stringify() function, and it can be faster than AoT compiled logic in the Bun

Benchmark on Linux

Some may suspect that Bun is based on the Safari browser's engine (JavaScriptCore), so it is poorly optimized for Windows, but shows normal performance on other operating systems such as Linux.

So I benchmarked it on Linux, but the results were the same. Bun is still much slower than NodeJS in the logic operations.

Top comments (11)

Collapse
 
atsepkov profile image
Alexander Tsepkov • Edited

I don’t get the point of the article, all you’ve proven is that a library hyper-optimized for Node and taking advantage of its hidden features doesn’t work well on Bun. No surprise there. The title claiming that this applies to all logical operations is nothing but clickbait.

Collapse
 
samchon profile image
Jeongho Nam

The validation and serialization code uses below expressions, and you are saying that these common expressions are hyper optimized only for NodeJS so that have not to use in Bun, right?

  • binary expression (===)
  • typeof expression
  • string concat expression
  • return expression
  • Number to String type casting
Collapse
 
vndre profile image
Andre

One very little detail was coincidentally omitted: the OP of this post is the creator of the Typia library and there's a chance they are biased in promoting their hard work. I will believe it when a benchmark is made by an unbiased non-related third party.

Collapse
 
msveshnikov profile image
Max Sveshnikov

Why to check types in runtime? Isn't it most idiotic idea ever?

Collapse
 
samchon profile image
Jeongho Nam

Request body data validation is the most famous case of runtime validation.

nestia.io/docs/core/TypedBody/

Collapse
 
hugohub profile image
Karlis Melderis

Oh no

You get unknowns (often any) from libs, external Apis (even if they claim their contract), raw SQL queries... Keep on adding cases when type is only on the paper

At these cases it's way safer to validate data before using it

Collapse
 
spicy_icy profile image
spicy_icy

nice work on typia 👍
i havent tried it myself but it seems to me that the benchmark is legit.
i hope the bun maintainers catch wind of this but im not sure if they can address this.
either way their github issues is flooded so i am not holding my breath.

Collapse
 
m0ltzart profile image
Roman

Would be an awesome benchmark to add to github.com/moltar/typescript-runti...

Collapse
 
cem_usta_fbe376c46cf78e1d profile image
Cem Usta

I wonder whats the state in Deno2

Collapse
 
khalid_achwaq_04fb3ca1d3d profile image
Khalid Achwaq

What about in Deno 🤔❓

Collapse
 
nabwinsaud profile image
Nabin

Can you show the repo what actually you are trying to do . Typia i don't see the starter repo for that to explore .