From 870d11bc2f06bf4e3705bd2d841ef65397462934 Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Sat, 24 Oct 2026 23:53:14 +0200 Subject: [PATCH] perf(builtin): inline fast paths for slice element stores An assignment to a slice element, including a compound one such as s[i] += v, writes through sliceElems and sliceSlot, which, like the helpers of the previous commit, tried a long chain of representations. Give them the same small fast path for a window object, a typed slice or a plain array, with the existing code in slow functions. A read-modify- write of a tensor element (Cogent Lab, s.Values[s.Index3To1D(i, j, k)] += v) takes 29 ns instead of 34 ns under Node 26. Signed-off-by: Randall C. O'Reilly --- gs/builtin/slice.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gs/builtin/slice.ts b/gs/builtin/slice.ts index fcbcf7c2d..f74187ca1 100644 --- a/gs/builtin/slice.ts +++ b/gs/builtin/slice.ts @@ -269,6 +269,22 @@ export class GoSlice { // sliceElems returns the array that holds the elements of a slice: the // backing array of a window, or the slice itself. export function sliceElems(slice: any): any[] { + // A window object, a typed slice and a plain array are handled here, in a + // function small enough for engines to inline into element stores. + if (slice instanceof GoSlice) { + return slice.backing + } + if (ArrayBuffer.isView(slice)) { + return slice as unknown as any[] + } + if (Array.isArray(slice) && (slice as any).__meta__ === undefined) { + return slice + } + return sliceElemsSlow(slice) +} + +// sliceElemsSlow is sliceElems for nil and proxied slices. +function sliceElemsSlow(slice: any): any[] { // A typed slice is a view of exactly its elements. if (isTypedSlice(slice)) { return slice as ArrayLike as any[] @@ -280,6 +296,28 @@ export function sliceElems(slice: any): any[] { // sliceSlot returns the index in sliceElems(slice) of element index of the // slice, which it checks against the slice's length. export function sliceSlot(slice: any, index: number): number { + // An index in range of a window object, a typed slice or a plain array is + // handled here, in a function small enough for engines to inline; + // sliceSlotSlow handles the other slices and panics. + if (slice instanceof GoSlice) { + if (index >= 0 && index < slice.length) { + return slice.offset + index + } + } else if (ArrayBuffer.isView(slice)) { + if (index >= 0 && index < (slice as TypedSlice).length) { + return index + } + } else if (Array.isArray(slice) && (slice as any).__meta__ === undefined) { + if (index >= 0 && index < slice.length) { + return index + } + } + return sliceSlotSlow(slice, index) +} + +// sliceSlotSlow is sliceSlot for the slices and indexes that its fast path +// does not handle. +function sliceSlotSlow(slice: any, index: number): number { // A nil slice has no elements. if (slice === null || slice === undefined) { outOfRangeIndex(index, 0)