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 <heaust.azure@gmail.com>
This commit is contained in:
Amp
2026-09-18 07:01:15 +00:00
co-authored by heaust
parent f324ff6bb2
commit a4f3eeddd6
+6 -4
View File
@@ -1,6 +1,8 @@
const views = Object.freeze({ f32: Float32Array, u32: Uint32Array, i32: Int32Array }); const views = Object.freeze({ f32: Float32Array, u32: Uint32Array, i32: Int32Array });
export class SharedRows { export class SharedRows {
#view;
constructor(buffer, descriptor) { constructor(buffer, descriptor) {
if (!(buffer instanceof SharedArrayBuffer)) throw new TypeError("ROWS_DESCRIPTOR"); if (!(buffer instanceof SharedArrayBuffer)) throw new TypeError("ROWS_DESCRIPTOR");
this.buffer = buffer; this.buffer = buffer;
@@ -11,6 +13,8 @@ export class SharedRows {
if (!views[descriptor.format] || descriptor.name !== (this.descriptor?.name ?? descriptor.name)) if (!views[descriptor.format] || descriptor.name !== (this.descriptor?.name ?? descriptor.name))
throw new TypeError("ROWS_DESCRIPTOR"); throw new TypeError("ROWS_DESCRIPTOR");
this.descriptor = Object.freeze(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; return this;
} }
@@ -18,10 +22,8 @@ export class SharedRows {
get rows() { return this.descriptor.rows; } get rows() { return this.descriptor.rows; }
get stride() { return this.descriptor.stride; } get stride() { return this.descriptor.stride; }
get format() { return this.descriptor.format; } get format() { return this.descriptor.format; }
get view() { /** One typed view over the whole array; replaced only when the descriptor changes. */
const View = views[this.format]; get view() { return this.#view; }
return new View(this.buffer, this.descriptor.offset, this.descriptor.bytes / View.BYTES_PER_ELEMENT);
}
row(index) { row(index) {
if (!Number.isInteger(index) || index < 0 || index >= this.rows) throw new RangeError("ROW_RANGE"); if (!Number.isInteger(index) || index < 0 || index >= this.rows) throw new RangeError("ROW_RANGE");