URL: https://bun.sh/blog/bun-v1.1.30#compile-to-bytecode-for-2x-faster-startup-time

Bun 1.1.30 came out last week. What got me intrigued is this new option to bun build which is --bytecode. With it you can create an executable, supposedly compiled partially to bytecode which means it can start even faster.

I tried it on my hylite CLI which is a CLI, built with Bun, but works in all versions of Node, that can syntax highlight code to HTML on the command line. Here's what I did:

First, without --bytecode


bun build --compile --outfile hylite-executable src/index.ts

Second, with --bytecode


bun build --compile --bytecode --outfile hylite-executable-b src/index.ts

Looking at the files

ls -lh | rg executable
-rwxrwxrwx    1 peterbe  staff    59M Oct 15 07:46 hylite-executable
-rwxrwxrwx    1 peterbe  staff    65M Oct 15 07:45 hylite-executable-b

So the one compiled with --bytecode is 6MB larger.

Benchmark


❯ hyperfine "bun run src/index.ts --help" "./hylite-executable --help" "./hylite-executable-b --help" --warmup=2
Benchmark 1: bun run src/index.ts --help
  Time (mean ± σ):      77.0 ms ±   2.1 ms    [User: 69.9 ms, System: 14.1 ms]
  Range (min … max):    74.6 ms …  85.1 ms    35 runs

Benchmark 2: ./hylite-executable --help
  Time (mean ± σ):      52.7 ms ±   0.6 ms    [User: 50.5 ms, System: 7.2 ms]
  Range (min … max):    51.7 ms …  54.0 ms    51 runs

Benchmark 3: ./hylite-executable-b --help
  Time (mean ± σ):      38.3 ms ±   0.7 ms    [User: 50.8 ms, System: 11.3 ms]
  Range (min … max):    36.7 ms …  40.2 ms    69 runs

Summary
  ./hylite-executable-b --help ran
    1.38 ± 0.03 times faster than ./hylite-executable --help
    2.01 ± 0.07 times faster than bun run src/index.ts --help

The numbers to focus on are at the bottom.

  1. Using this new --bytecode option makes it start 1.38x faster than without.
  2. Using the compiled executable is 2.01x faster than running bun run ... directly

Conclusion

It works, but strangely to make this work I had to make this change:


-await main(code, {
+main(code, {
  wrapped: options.wrapped,
  htmlWrap: options.htmlWrap,
  language: options.language,
  css: options.css,
  previewServer: options.previewServer,
  outputFile: options.outputFile,
  listCss: options.listCss,
  version: options.version,
});

async function main(
  code: string,

Otherwise, you get this error:


❯ bun build --compile --bytecode --outfile hylite-executable-b src/index.ts
66 | await main(code, {
           ^
error: "await" can only be used inside an "async" function
    at /Users/peterbe/dev/JAVASCRIPT/BUN/hylite/src/index.ts:66:7

Strangely, this new option dictates the top-level await. Didn't ponder it much but a curious thing.

Comments

Your email will never ever be published.

Related posts