Repository navigation
Allocation-free matrix construction + deprecate index helpers (#70) - #69
Merged
Merged
Conversation
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
from
October 17, 2026 11:31
8f4cf0e to
fad8f8c
Compare
ctreffs
force-pushed
the
perf/inlinable
branch
from
October 17, 2026 12:18
10f0f52 to
beff349
Compare
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
from
October 17, 2026 12:18
fad8f8c to
5538593
Compare
ctreffs
force-pushed
the
perf/inlinable
branch
from
October 17, 2026 12:48
beff349 to
19cb66d
Compare
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
from
October 17, 2026 12:48
5538593 to
1d23f99
Compare
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
from
October 17, 2026 13:11
1d23f99 to
29586ba
Compare
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
2 times, most recently
from
October 17, 2026 13:54
6010506 to
d5eefff
Compare
Matrix{2,3,4}.init(_ column0, ...) built an Array of columns and passed
it to Storage(columns), so every matrix construction allocated, including
every non-SIMD matrix multiply. init(_ values:) sliced into arrays as
well, and iteration allocated through flatMap'd arrays (non-SIMD
storages), [x, y, z, w] arrays (simd quaternions) and AnyIterator
(`elements`).
- Add init(_ column0:, _ column1:, ...) as a Storage*Protocol
requirement. The simd matrix types already provide it; the non-SIMD
storages implement it, and their array initializers delegate to it.
- Matrix column/array/values initializers go through the column
initializer; no intermediate arrays.
- Non-SIMD storages use the default IndexingIterator over themselves
instead of building an array; simd quaternions iterate their vector via
SIMDScalarIterator.
- Matrix `elements` is Array(storage); SIMD `elements` maps indices
instead of going through AnyIterator.
Non-SIMD 4x4 multiply in an external release-mode consumer: 156 ms ->
22 ms for 5M multiplies. The SIMD path is unchanged.
Tests: MatrixConstructionTests checks that all construction paths agree
and produce column-major layout, and that matrices, quaternions and
vectors iterate in order.
Claude-Session: https://claude.ai/code/session_011WSUtoLptjea3s3iC5wTNC
ctreffs
force-pushed
the
perf/allocation-free-construction
branch
from
October 17, 2026 14:05
d5eefff to
2ce7789
Compare
This was referenced Oct 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack 4+5/5 — base:
master. Also contains #70 (deprecate the public matrix index helpers), which was merged into this branch; see #70 for its description and tests.Problem
Matrix{2,3,4}.init(_ column0, …)built anArrayof columns and handed it toStorage(columns), so every matrix construction allocated. That includes every non-simdmultiply, which ends withMat4x4d(Vec4d(…), …).init(_ values:)sliced the array into more arrays.[column0, …].flatMap { $0 }, the simd quaternions built[x, y, z, w], andelementswent through the type-erasedAnyIterator.Change
Storage*Protocolrequirement:init(_ column0:, _ column1:, …). The simd matrix types (simd_float4x4etc.) already have it, so their conformance needs no new code. The non-simd storages implement it, and their[Column]initializers delegate to it.[Vector]and[Value]initializers keep their preconditions.makeIterator. They areRandomAccessCollections and now use the defaultIndexingIterator<Self>.vectorwithSIMDScalarIterator.Matrix.elementsisArray(storage), andSIMD.elementsmapsindices.API note: the associated
Iteratortype of the non-simd storages and the simd quaternion storage changes, fromIndexingIterator<[T]>toIndexingIterator<Self>/SIMDScalarIterator<SIMD4<T>>. This only breaks code that names those types explicitly.Tests
MatrixConstructionTestschecks, for all six matrix types, that the column,[column],[value]and array-literal initializers produce the same matrix in column-major layout, and thatelements,Array(m)andfor … inyield the same order. It also checks quaternion and SIMD element order. Bothcheck-inlinableconfigurations still pass.Benchmark
External consumer package,
-c release, 5Mmat4 * mat4:https://claude.ai/code/session_011WSUtoLptjea3s3iC5wTNC