From a4f3eeddd6a283b6346c32ecc4ef1053da85df6a Mon Sep 17 00:00:00 2001 From: Amp Date: Fri, 18 Sep 2026 07:01:15 +0000 Subject: [PATCH] core: cache the whole-array SharedRows view view() allocated a fresh typed array on every access (and row() a second subarray); the view is now built once per descriptor in update(). Amp-Thread-ID: https://ampcode.com/threads/T-01a0b2dd-db32-712d-99ce-12ce4a86d979 Co-authored-by: Heaust Azure --- core/index.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/index.js b/core/index.js index 996d831..ccf315a 100644 --- a/core/index.js +++ b/core/index.js @@ -1,6 +1,8 @@ const views = Object.freeze({ f32: Float32Array, u32: Uint32Array, i32: Int32Array }); export class SharedRows { + #view; + constructor(buffer, descriptor) { if (!(buffer instanceof SharedArrayBuffer)) throw new TypeError("ROWS_DESCRIPTOR"); this.buffer = buffer; @@ -11,6 +13,8 @@ export class SharedRows { if (!views[descriptor.format] || descriptor.name !== (this.descriptor?.name ?? descriptor.name)) throw new TypeError("ROWS_DESCRIPTOR"); this.descriptor = Object.freeze(descriptor); + const View = views[descriptor.format]; + this.#view = new View(this.buffer, descriptor.offset, descriptor.bytes / View.BYTES_PER_ELEMENT); return this; } @@ -18,10 +22,8 @@ export class SharedRows { get rows() { return this.descriptor.rows; } get stride() { return this.descriptor.stride; } get format() { return this.descriptor.format; } - get view() { - const View = views[this.format]; - return new View(this.buffer, this.descriptor.offset, this.descriptor.bytes / View.BYTES_PER_ELEMENT); - } + /** One typed view over the whole array; replaced only when the descriptor changes. */ + get view() { return this.#view; } row(index) { if (!Number.isInteger(index) || index < 0 || index >= this.rows) throw new RangeError("ROW_RANGE");