跪拜 Guibai
← All articles
Frontend · Backend · Programmer

MoonBit, Rust, and Go Compete on WASM Binary Size and Raw Speed

By 前端之虎陈随易 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

WASM is spreading beyond the browser into edge functions, serverless, and plugin systems where cold-start latency and binary size directly affect cost and user experience. These numbers show that language choice alone can create a 10,000x gap in binary size and a 1,000x gap in call latency, making the compiler target a first-order infrastructure decision.

Summary

The same recursive and iterative Fibonacci algorithm, implemented with 64-bit integers in MoonBit, Rust, and Go, was compiled to WASM and benchmarked in Node.js. MoonBit produced the smallest binary at 211 bytes and led in speed, especially in the iterative test where it clocked 12–15 ns versus Rust's 35–43 ns. Go's standard compiler output a 1.84 MB binary and ran in microseconds due to its bundled runtime and GC overhead.

Rust remains the ecosystem leader with a 286-byte binary and performance in the same league as MoonBit, backed by mature tooling like wasm-bindgen and wasm-pack. MoonBit's compiler optimizations for WASM are evident, though its library ecosystem is still young. Go's size and call overhead make it a poor fit for cold-start-sensitive workloads unless teams already have substantial Go code to reuse.

The test surfaces a clear trade-off: MoonBit and Rust deliver tiny, fast WASM modules suitable for edge functions and serverless, while standard Go's design choices prioritize its runtime model over minimal output.

Takeaways
MoonBit's WASM binary is 211 bytes, Rust's is 286 bytes, and Go's standard compiler produces 1.84 MB.
In the iterative Fibonacci benchmark, MoonBit ran at 12–15 ns, Rust at 35–43 ns, and Go at 16–21 µs — a three-order-of-magnitude spread.
Go's WASM performance penalty comes from its bundled runtime, GC, and the JS interop layer, not from algorithmic inefficiency.
MoonBit compiles to WASM, JavaScript, and native backends, with a type system that includes pattern matching and GC.
Rust's WASM toolchain — wasm-bindgen, wasm-pack, wasm-opt — remains the most mature and well-documented option for production teams.
TinyGo is a better fit than standard Go for WASM scenarios where binary size matters.
Conclusions

MoonBit's iterative performance lead over Rust (roughly 3x faster in nanoseconds) is notable and suggests its WASM backend generates unusually tight code for simple loops, though a single microbenchmark cannot confirm this generalizes.

The 10,000x binary-size gap between Go and the other two languages is not a flaw but a deliberate architectural trade-off: Go ships its runtime, which makes it viable for porting existing Go services to WASM but disqualifies it for cold-start-sensitive serverless functions.

These results imply that WASM's language ecosystem is bifurcating into minimal-runtime languages (Rust, MoonBit, C) optimized for small modules and managed-runtime languages (Go, potentially Java) that prioritize feature parity over output size.

Concepts & terms
WASM (WebAssembly)
A binary instruction format for a stack-based virtual machine, designed as a portable compilation target for languages like C, C++, Rust, and Go. It runs in browsers and standalone runtimes such as Node.js and Wasmtime.
MoonBit
A relatively new programming language designed with first-class WASM and cloud-native support. It features a strong type system, pattern matching, and garbage collection, and can compile to WASM, JavaScript, and native code.
TinyGo
An alternative Go compiler that targets small binaries and embedded systems, including WASM. It produces much smaller WASM outputs than the standard Go compiler by using a lighter runtime.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗