This is an unscientific comparison update from previous blog posts that compared Node and Bun, but didn't compare with Deno.

Temperature conversion

From Converting Celsius to Fahrenheit round-up it compared a super simple script that just prints a couple of lines of text after some basic computation. If you include Deno on that run you get:


❯ hyperfine --shell=none --warmup 3 "bun run conversion.js" "node conversion.js" "deno run conversion.js"
Benchmark 1: bun run conversion.js
  Time (mean ± σ):      22.2 ms ±   2.1 ms    [User: 12.4 ms, System: 8.6 ms]
  Range (min … max):    20.6 ms …  36.0 ms    136 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

...

Summary
  bun run conversion.js ran
    1.97 ± 0.35 times faster than deno run conversion.js
    2.41 ± 0.39 times faster than node conversion.js

Note that bun run and deno run both support .ts files whereas Node needs it to be .js (unless you use something like --require @swc-node/register). So in this benchmark, I let bun run and deno run use the .js version.


❯ deno --version
deno 1.45.2 (release, x86_64-apple-darwin)
v8 12.7.224.12
typescript 5.5.2

❯ node --version
v20.14.0

❯ bun --version
1.1.21

Leibniz formula

In Leibniz formula for π in Python, JavaScript, and Ruby I wrote a simple program that computes the value of π using the Leibniz formula. It became a comparison of that code implementation in Python vs. Ruby vs. Node.

But let's redo the test with Bun and Deno too. Code was


let sum = 0;
let estimate = 0;
let i = 0;
const epsilon = 0.0001;

while (Math.abs(estimate - Math.PI) > epsilon) {
  sum += (-1) ** i / (2 * i + 1);
  estimate = sum * 4;
  i += 1;
}
console.log(
  `After ${i} iterations, the estimate is ${estimate} and the real pi is ${Math.PI} ` +
    `(difference of ${Math.abs(estimate - Math.PI)})`
);

Running it once, it prints:


❯ deno run pi.js
After 10000 iterations, the estimate is 3.1414926535900345 and the real pi is 3.141592653589793 (difference of 0.0000999999997586265)

Running them becomes more of a measurement of how fast the programs start rather than how fast they run, but it's nevertheless and interesting to know too:


❯ hyperfine --warmup 3 "node pi.js" "bun run pi.js" "deno run pi.js"
Benchmark 1: node pi.js
  Time (mean ± σ):      54.9 ms ±   6.5 ms    [User: 42.6 ms, System: 11.3 ms]
  Range (min … max):    50.2 ms …  83.9 ms    48 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

...

Summary
  bun run pi.js ran
    1.92 ± 1.01 times faster than deno run pi.js
    2.37 ± 0.31 times faster than node pi.js

Conclusion

Both of these programs that I'm comparing with are super trivial and take virtually no time to run, once they've started. So it becomes more a test of warm-start performance. Alas, it's cool to see that both Deno and Bun make a better job of it here. Bun is almost 2x faster than Deno and 2.5x faster than Node.

Comments

Your email will never ever be published.

Related posts