Gk.putty P4DocsEnvironment & Energy
Related
Transportation Secretary Sean Duffy Balances Reality TV Filming with Official Duties Amid Oil Price ConcernsV8 Engine Deploys Speculative Optimizations for WebAssembly, Boosting WasmGC Performance by up to 50%Google Chrome M137 Delivers Record WebAssembly Performance via Speculative Inlining and DeoptimizationThe Alarming Role of AI Chatbots in Escalating Gender-Based Violence and the Case for RegulationTank Pad Ultra: A Rugged Tablet with a Built-in 1080p Projector – Everything You Need to KnowUK Avoids £1.7bn Gas Imports Since Iran War Began, Thanks to Record Wind and Solar OutputYour Guide to Free May Wallpapers: Download and Contribute in 5 Easy StepsMastering XPENG VLA 2.0: A Step-by-Step Guide to Sporty, Autonomous Driving

V8 JavaScript Engine's 2.5x Performance Leap: Mutable Heap Numbers Eliminate Allocation Bottleneck

Last updated: 2026-05-15 02:19:21 · Environment & Energy

V8 Achieves 2.5x Speedup in Async File System Benchmark

The V8 JavaScript engine has delivered a stunning 2.5x performance improvement in the async-fs JetStream2 benchmark, thanks to a new optimization that makes heap numbers mutable. The change eliminates repeated memory allocations during Math.random calls, addressing a hidden bottleneck in real-world JavaScript code.

V8 JavaScript Engine's 2.5x Performance Leap: Mutable Heap Numbers Eliminate Allocation Bottleneck
Source: v8.dev

"The seed variable in a custom Math.random was causing a new heap object allocation on every invocation," explained a V8 engineer. "By making heap numbers mutable, we avoid the allocation entirely, allowing us to update the value in place."

The Bottleneck: Immutable Heap Numbers

In JavaScript, numbers can be stored as either Small Integers (SMI) or as HeapNumber objects on the heap. SMIs are fast—they fit directly in a 32-bit tagged value. But numbers that exceed the SMI range or have fractional parts must be stored as immutable HeapNumber objects. Each update to such a number requires allocating a new HeapNumber, which triggers garbage collection pressure.

The async-fs benchmark uses a custom deterministic Math.random that updates a seed variable on every call. This seed is stored in a ScriptContext, a data structure that holds variables accessible within a script. Because seed is a double-precision value, it was stored as a HeapNumber—immutable by default. Profiling revealed that each call to Math.random allocated a new HeapNumber, causing significant slowdown.

Mutation to the Rescue

The V8 team recognized that this pattern—a variable updated in a tight loop—is exactly where immutable HeapNumbers fail. Their solution: allow certain HeapNumber objects to be mutated directly, updating the 64-bit double value in place without allocating new objects. This optimization required changes to V8's object representation and garbage collector to safely track mutable heap numbers.

"We were able to treat the seed slot as a mutable container," said a V8 performance engineer. "This cuts the allocation overhead to zero for that hotspot." The result: a 2.5x improvement on async-fs and a noticeable overall gain in JetStream2 scores.

Background: V8's Tagged Values and ScriptContexts

V8 uses a tagged representation for all JavaScript values. On 64-bit systems, each value is a 32-bit pointer-sized tag combined with data. The least significant bit distinguishes between SMIs (bit 0) and heap object pointers (bit 1). SMIs store integers shifted left by one bit. Heap objects include HeapNumbers, which hold a 64-bit floating-point number. Traditionally, HeapNumbers are immutable to simplify garbage collection and object sharing.

ScriptContexts store local variables for a script as an array of tagged values. For seed, which holds a non-integer, V8 stored a pointer to an immutable HeapNumber. With the new optimization, that slot now points to a mutable HeapNumber that can be updated directly.

What This Means: Real-World Impact

While this optimization was inspired by the async-fs benchmark, the pattern it addresses appears in many real-world applications. Any code that repeatedly updates a large or fractional number—such as physics simulations, financial calculations, or game state—can benefit from mutable heap numbers.

"This change isn't just a synthetic benchmark win," noted a V8 team member. "We see similar allocation patterns in production code, so users of V8-powered applications will likely notice improved responsiveness and lower memory usage."

The V8 team plans to extend the mutable heap number concept to other contexts in future releases, potentially unlocking further performance gains across the engine. For now, the 2.5x improvement in async-fs stands as a clear demonstration of how attacking allocation bottlenecks can yield dramatic speedups.

Learn more about V8's architecture.