V8 JavaScript Engine's 2.5x Performance Leap: Mutable Heap Numbers Eliminate Allocation Bottleneck
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.
"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.
Related Articles
- 6 Key Facts About the Recent Solar Flare and Its Potential to Spark Auroras
- How EU Governments Can Shield Drivers from Surging Oil Prices: A Q&A Guide
- How to Connect with the Flutter Core Team in 2026: A Step-by-Step Guide
- Revitalize Your Winter: Smart Energy Solutions for Australian Homes
- Flutter Core Team Announces Global Tour for 2026: Key Events and Developer Engagements Revealed
- Flutter and Dart Websites Rebuilt with Jaspr – Unified Stack Ends Fragmented Tooling
- Slash Your Electric Bill to Nearly Zero: Power Your Home and EV on Solar
- Green Rocks in Spanish Pyrenees Cave Suggest Copper Smelting Over 7,000 Years Ago