From aa8409893c55c11befc5eb2e80254048596df207 Mon Sep 17 00:00:00 2001 From: Beforerr Date: Sat, 16 May 2026 20:18:26 -0700 Subject: [PATCH] Reduce invalidations from `using StaticArrays` (#1074) Three small signature tweaks that cut invalidated MIs ~57% (2030 -> 875) and remove two whole invalidation trees: - `eachindex(::IndexLinear, ::StaticArray)`: narrow to rank N >= 2 via a `Union{StaticArray{<:Tuple,T,N} where T for N in 2:32...}`. Vectors fall through to `Base.axes1` which already returns `SOneTo`. Concrete `N` in the signature is what makes the invalidator see `Union{}` against `AbstractVector{X}`; a `where N` clause does not. - `any`/`all`/`count` with a function argument: drop the specialised methods. Base routes `any(f, A)` through `mapreduce(f, |, A)`, and we already specialise `mapreduce` for `StaticArray`, so the fast path is preserved. The removed `::Bool` cast was defensive and not needed for static eltypes; the explicit `init=false` matches the default for `|`/`&`/`+`. - `setindex!(::TrivialView, inds...)`: add the missing `v` slot. Co-Authored-By: Claude Opus 4.7 --- src/abstractarray.jl | 3 ++- src/mapreduce.jl | 7 ++----- src/util.jl | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/abstractarray.jl b/src/abstractarray.jl index b7806fd6..91ad7375 100644 --- a/src/abstractarray.jl +++ b/src/abstractarray.jl @@ -13,7 +13,8 @@ Base.axes(s::StaticArrayLike) = _axes(Size(s)) map(SOneTo, sizes) end -Base.eachindex(::IndexLinear, a::StaticArray) = SOneTo(length(a)) +const _StaticArrayRankGE2 = Union{(StaticArray{<:Tuple, T, N} where T for N in 2:32)...} +Base.eachindex(::IndexLinear, a::_StaticArrayRankGE2) = SOneTo(length(a)) # Base.strides is intentionally not defined for SArray, see PR #658 for discussion Base.strides(a::MArray) = Base.size_to_strides(1, size(a)...) diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 899ec2ab..e264ada5 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -299,13 +299,10 @@ reduce(::typeof(hcat), A::StaticArray{<:Tuple,<:StaticVecOrMatLike}) = @inline prod(f::Union{Function, Type}, a::StaticArray{<:Tuple,T}; dims::D=:, init=_InitialValue()) where {D, T} = _mapreduce(f, *, dims, init, Size(a), a) @inline count(a::StaticArray{<:Tuple,Bool}; dims::D=:, init=0) where {D} = _reduce(+, a, dims, init) -@inline count(f, a::StaticArray; dims::D=:, init=0) where {D} = _mapreduce(x->f(x)::Bool, +, dims, init, Size(a), a) -@inline all(a::StaticArray{<:Tuple,Bool}; dims::D=:) where {D} = _reduce(&, a, dims, true) # non-branching versions -@inline all(f::Function, a::StaticArray; dims::D=:) where {D} = _mapreduce(x->f(x)::Bool, &, dims, true, Size(a), a) +@inline all(a::StaticArray{<:Tuple,Bool}; dims::D=:) where {D} = _reduce(&, a, dims, true) -@inline any(a::StaticArray{<:Tuple,Bool}; dims::D=:) where {D} = _reduce(|, a, dims, false) # (benchmarking needed) -@inline any(f::Function, a::StaticArray; dims::D=:) where {D} = _mapreduce(x->f(x)::Bool, |, dims, false, Size(a), a) # (benchmarking needed) +@inline any(a::StaticArray{<:Tuple,Bool}; dims::D=:) where {D} = _reduce(|, a, dims, false) @inline Base.in(x, a::StaticArray) = _mapreduce(==(x), |, :, false, Size(a), a) diff --git a/src/util.jl b/src/util.jl index 6079c36d..47145c99 100644 --- a/src/util.jl +++ b/src/util.jl @@ -49,7 +49,7 @@ end size(a::TrivialView) = size(a.a) getindex(a::TrivialView, inds...) = getindex(a.a, inds...) -setindex!(a::TrivialView, inds...) = (setindex!(a.a, inds...); a) +setindex!(a::TrivialView, v, inds...) = (setindex!(a.a, v, inds...); a) Base.IndexStyle(::Type{<:TrivialView{A}}) where {A} = IndexStyle(A) TrivialView(a::AbstractArray{T,N}) where {T,N} = TrivialView{typeof(a),T,N}(a)