julia> struct ConstVector <: AbstractVector{Int}
x :: Int
len :: Int
end
julia> Base.size(c::ConstVector) = (c.len,)
julia> @inline function Base.getindex(c::ConstVector, i::Int)
@boundscheck checkbounds(c, i)
c.x
end
julia> @inline function Base.iterate(c::ConstVector, i=1)
i > length(c) && return nothing
return c.x, i+1
end
julia> c = ConstVector(42, 100000000);
julia> using BenchmarkTools
julia> @btime any(iszero, $c);
41.775 ms (0 allocations: 0 bytes)
Is there a way (short of specializing any and other reduction functions) to indicate that all elements are identical, and that the loop may be avoided in this case? Shouldnβt the specialized iterate be enough to declare this?
This is completely unrelated to type instability, which doesnβt hurt here either way due to the small union optimization (TL;DR of which is dispatch on small unions is inlined). If that were the problem, pretty much no vectorization of any loop would be possible, at all.
This is interesting, and it does seem to work within a function even if the length isnβt a constant:
julia> f(x, n) = begin
c = ConstVector(x, n)
any(iszero, c)
end
f (generic function with 1 method)
julia> @btime f(42, 10000000);
2.971 ns (0 allocations: 0 bytes)