Skip to content

perf(compiler): read slice elements by the representation of their type - #534

Merged
paralin merged 1 commit into
s4wave:devfrom
cogentcore:perf/typed-slice-index
Oct 25, 2026
Merged

paralin merged 1 commit into
s4wave:devfrom
cogentcore:perf/typed-slice-index

Conversation

@rcoreilly

Copy link
Copy Markdown
Contributor

A read of a slice element lowered to arrayIndex, which tests each representation of a collection in turn (window object, typed array, plain array). Where engines do not inline it, as in functions with many element reads, every call pays for the tests that do not apply, and its property loads see every kind of collection in the program.

The static type of a slice tells which representation it usually has: a typed array if its element type is held in one (typedSliceArray), and otherwise a plain array or a window object. This lowers a read of such a slice's element to typedSliceIndex or plainSliceIndex, which test that representation first in a single condition and otherwise call arrayIndex, so behavior is identical for every representation and only the speed depends on the choice. Slices whose element type has a type parameter, and other indexed values, keep arrayIndex. Both helpers are added to isSimpleLoweredOperand's pure readers, as arrayIndex is, so stores through them keep their form.

This follows the array version in 30f64fd. A neural network update function benchmark under Node 26 (a dozen tensor element reads and writes through Cogent Lab's fixed-arity accessors, where most of the cost is reading Shape.Strides, a []int) goes from 21 ns to 15 ns per element access.

New unit tests check that both helpers read every representation (plain array, window, typed array, typed window, proxy) as arrayIndex does and panic with the same messages. 155 compliance outputs change, and only in the name of the helper. The full Go test suite, typecheck and vitest pass.

A read of a slice element lowered to arrayIndex, which tests the
representations of a collection in turn (window object, typed array,
plain array). Where engines do not inline it, as in functions with many
element reads, each call pays for the tests that do not apply, and the
property loads in arrayIndex see every kind of collection in the program.

The type of a slice tells which representation it usually has: a typed
array if its element type is held in one (see typedSliceArray), and
otherwise a plain array or a window object. A read of an element of such
a slice now calls typedSliceIndex or plainSliceIndex, which test that
representation first in one condition, and are otherwise arrayIndex, so
only the speed depends on the choice. Slices whose element type has a
type parameter, and other indexed values, still use arrayIndex. Both
helpers are pure readers that may be evaluated twice, as arrayIndex is.

In a benchmark of a neural network update function under Node 26 (a
dozen reads and writes of tensor elements through Cogent Lab's
fixed-arity accessors), an element access takes 15 ns instead of 21 ns.

Signed-off-by: Randall C. O'Reilly <oreilly@ucdavis.edu>
@paralin
paralin changed the base branch from master to dev October 25, 2026 18:36
@paralin
paralin merged commit 6596759 into s4wave:dev Oct 25, 2026
7 checks passed
@paralin

paralin commented Oct 25, 2026

Copy link
Copy Markdown
Member

Landed on master as 32f00e5, rebased onto the batch #532 to #550, with regenerated fixtures in fca8071.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants