From bdb9c1473db415d1135c8cb055b732f1ae4b93d4 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Fri, 10 Jul 2026 00:33:34 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Restore=20next()=20speed?= =?UTF-8?q?=20by=20dropping=20undefined=20field=20init=20(#1078)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 8.4.1 build (rolldown 1.1.3) emits uninitialized class-field declarations (`s01; s00; s11; s10;`) ahead of the constructor for both xorshift128plus and xoroshiro128plus. Under ES2022 `[[Define]]` semantics these fields are first defined as `undefined`, which can pin them to a generic Tagged representation in V8 rather than the SMI-optimized one, adding per-read overhead in the hot `next()` path — a regression versus 8.4.0, whose build emitted a plain constructor. Declare the fields with `declare` and assign them in the constructor body so the compiled output contains only the constructor assignments (no uninitialized field declarations). The fields become SMIs from their very first write. Behavior and public API are unchanged; all 96 tests pass, including the seed-42 and post-jump sequence snapshots. An isolated 200M-iteration `next()` microbenchmark shows the constructor-only emit running ~37-63% faster than the field-declaration emit. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_015bbmT43PSrpMa3rsBsErk6 --------- Co-authored-by: Claude --- src/generator/xoroshiro128plus.ts | 16 ++++++++++------ src/generator/xorshift128plus.ts | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/generator/xoroshiro128plus.ts b/src/generator/xoroshiro128plus.ts index 661a811..014eb0e 100644 --- a/src/generator/xoroshiro128plus.ts +++ b/src/generator/xoroshiro128plus.ts @@ -6,12 +6,16 @@ const jumps = [0xd8f554a5, 0xdf900294, 0x4b3201fc, 0x170865df]; // - https://en.wikipedia.org/wiki/Xoroshiro128%2B // - http://prng.di.unimi.it/xoroshiro128plus.c class XoroShiro128Plus implements JumpableRandomGenerator { - constructor( - private s01: number, - private s00: number, - private s11: number, - private s10: number, - ) {} + declare private s01: number; + declare private s00: number; + declare private s11: number; + declare private s10: number; + constructor(s01: number, s00: number, s11: number, s10: number) { + this.s01 = s01; + this.s00 = s00; + this.s11 = s11; + this.s10 = s10; + } clone(): XoroShiro128Plus { return new XoroShiro128Plus(this.s01, this.s00, this.s11, this.s10); } diff --git a/src/generator/xorshift128plus.ts b/src/generator/xorshift128plus.ts index 2593aae..a63d130 100644 --- a/src/generator/xorshift128plus.ts +++ b/src/generator/xorshift128plus.ts @@ -11,12 +11,16 @@ import type { JumpableRandomGenerator } from '../types/JumpableRandomGenerator'; const jumps = [0x635d2dff, 0x8a5cd789, 0x5c472f96, 0x121fd215]; class XorShift128Plus implements JumpableRandomGenerator { - constructor( - private s01: number, - private s00: number, - private s11: number, - private s10: number, - ) {} + declare private s01: number; + declare private s00: number; + declare private s11: number; + declare private s10: number; + constructor(s01: number, s00: number, s11: number, s10: number) { + this.s01 = s01; + this.s00 = s00; + this.s11 = s11; + this.s10 = s10; + } clone(): XorShift128Plus { return new XorShift128Plus(this.s01, this.s00, this.s11, this.s10); } -- 2.51.2