Open
Description
It would be nice to be able to check if a function is pure and fast for free at runtime using effect analysis. is_pure_and_fast(f, T::Type{<:Tuple})
returns true if f
, applied to inputs of type T
, is pure an fast. False negatives are okay.
is_pure_and_fast(identity, Tuple{Matrix{Foat64}}) == true
is_pure_and_fast(x -> x^3 + x^2 - 3, Tuple{Foat64}) == true
is_pure_and_fast(x -> iterated_md5_hash(x, iters=10_000), Tuple{String}) == false
is_pure_and_fast(x -> rand(), Tuple{}) == false
It would also be nice to get all of effect analysis for free at runtime.
The motivating usecase here is when computing findall
, it is often more efficient to traverse the input twice than to incrementally build an output, but only if f
is fast and pure.
function findall(f, x::AbstractArray)
if is_pure_and_fast(f ∘ getindex, Tuple{typeof(x), Int}) # evaluated at compile time
_findall(Iterators.map(f, x))
else
_findall(f.(x))
end
end
function _findall(x)
out = Vector{Int}(undef, count(x)+1)
j = 1
@inbounds for (i,v) in enumerate(x)
out[j] = i
j += v
end
resize!(out, j-1)
out
end
Activity