I’ve wondered for a while whether it is possible to abuse the broadcast machinery to do something like this (basically to avoid materialize
being called on the lazy broadcasted object). I’ve not found a nice way of doing it (i.e., a way that doesn’t obscure/muddy the semantics of dot broadcasting) but here is a not-so-nice way of doing it.
myany(x) = any(x) # avoid piracy!
Broadcast.broadcasted(::typeof(myany), x) = myany(x) # exploit the fact that the broadcasted object is iterable
On a simple test case this gives
julia> a = rand(10000) ; b = rand(10000) ; c = rand(10000) ;
julia> @btime any(($a .> 0.5) .& ($b .> 0.5) .& ($c .> 0.5))
19.828 μs (3 allocations: 5.55 KiB)
true
julia> @btime myany.(($a .> 0.5) .& ($b .> 0.5) .& ($c .> 0.5))
59.478 ns (10 allocations: 240 bytes)
true
So much faster than the original case but not as fast as the anonymous function or generator expression versions as mentioned above (and it allocates more).
julia> @btime any(((aa, bb, cc),) -> (aa > 0.5) && (bb > 0.5) && (cc > 0.5), zip($a, $b, $c))
13.820 ns (2 allocations: 64 bytes)
true
julia> @btime any((aa > 0.5) && (bb > 0.5) && (cc > 0.5) for (aa, bb, cc) in zip($a, $b, $c))
16.822 ns (3 allocations: 80 bytes)
true