I share some considerations while waiting for further information from someone who knows better the internal functioning of the functions involved.
First of all, the @imiq loop is not “simple” or, to be more precise, the way in which it exploits the particularity of the problem to avoid doing the N ifs that some other proposals do is not entirely simple.
Below are some comparisons between the following functions and the use of count()
function cepsac(a,b, cnd)
cnt=0
for (x,y) in zip(a,b)
if cnd(x,y)
cnt+=1
end
end
cnt
end
function cepsac1(a,b, cnd)
cnt=0
for i in eachindex(a)
cnt+=cnd(a[i],b[i])
end
cnt
end
julia> @btime cepsac1($a,$b, (x,y)->(x - 0.5)^2 + (y - 0.5)^2 <= 0.25)
578.800 μs (0 allocations: 0 bytes)
822831
julia> @btime cepsac($a,$b, (x,y)->(x - 0.5)^2 + (y - 0.5)^2 <= 0.25)
884.200 μs (0 allocations: 0 bytes)
822831
julia> @btime count(x-> ($a[x]-0.5)^2 + ($b[x]-0.5)^2 <= 0.25, eachindex($a))
585.400 μs (0 allocations: 0 bytes)
822831
It seems that count() manages to avoid using if statements and just do sums (taking advantage of the fact that false cases do not contribute to the total)
Another consideration that I wanted to submit to other comments is the following.
Starting from Dan’s observation that optimization could depend on the specificity of the problem (in abstract on the OP one could answer that the solution is N/2), I was wondering how the different solutions behave depending on the fraction p with respect to the total of cases that make the condition true.
In other words, how do the sum and if then statements weigh.
below are the extreme cases of only if then and only sums.
julia> @btime cepsac($a,$b, (x,y)->x+y>2)
756.200 μs (0 allocations: 0 bytes)
0
julia> @btime cepsac1($a,$b, (x,y)->x+y>2)
535.600 μs (0 allocations: 0 bytes)
0