Skip to content

Commit d20ca48

Browse files
authored
Make findall faster for AbstractArrays (#37177)
The `findall` fallback is quite slow when predicate is a small function compared with generating a logical index using `broadcast` and calling `findall` on it to compute integer indices. The gain is most visible when predicate is true for a large proportion of entries, but it's there even when all of them are false. The drawback of this approach is that it requires allocating a vector of `length(a)/8` bytes whatever the number of returned indices.
1 parent 9921e8c commit d20ca48

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

base/array.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,10 @@ julia> findall(x -> x >= 0, d)
21422142
"""
21432143
findall(testf::Function, A) = collect(first(p) for p in pairs(A) if testf(last(p)))
21442144

2145+
# Broadcasting is much faster for small testf, and computing
2146+
# integer indices from logical index using findall has a negligible cost
2147+
findall(testf::Function, A::AbstractArray) = findall(testf.(A))
2148+
21452149
"""
21462150
findall(A)
21472151
@@ -2439,7 +2443,8 @@ function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:
24392443
end
24402444
# issorted fails for some element types so the method above has to be restricted
24412445
# to element with isless/< defined.
2442-
findall(pred::Fix2{typeof(in)}, x::Union{AbstractArray, Tuple}) = _findin(x, pred.x)
2446+
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
2447+
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
24432448

24442449
# Copying subregions
24452450
function indcopy(sz::Dims, I::Vector)

0 commit comments

Comments
 (0)