Hi,
In Julia 1.3.x version extrema function use to be much slower that minimum + maximum execution. At that time I wrote my own specialized extrema function and gained ~x3 by avoiding one test out of the two in each iteration (algo change).
I recently noticed that this extrema performance issue was corrected in the current 1.5.3. and now extrema is performing as fast as mimimum + maximum.
However when replicating the algo change trying to avoid one test on each iteration I got a counter perf by a factor of ~5
See test code and bench results below.
Anyone has an idea on how to keep the algo improvement and gain in perf? It seems that the branching is fooling LLVM optimization.
Thanks
using BenchmarkTools
n = 1000;
a = rand(1:n, n);
function extrema1(a::Vector{Int64})
vmin = vmax = @inbounds a[1]
for i = 2:length(a)
v = @inbounds a[i]
if v < vmin
vmin = v
end
if v > vmax
vmax = v
end
end
return (vmin, vmax)
end
function extrema2(a::Vector{Int64})
vmin = vmax = @inbounds a[1]
for i = 2:length(a)
v = @inbounds a[i]
if v < vmin
vmin = v
elseif v > vmax
vmax = v
end
end
return (vmin, vmax)
end
function extrema3(a::Vector{Int64})
vmin = vmax = @inbounds a[1]
for i = 2:length(a)
v = @inbounds a[i]
if v < vmin
vmin = v
continue
end
if v > vmax
vmax = v
end
end
return (vmin, vmax)
end
julia> @benchmark extrema($a)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 272.136 ns (0.00% GC)
median time: 272.755 ns (0.00% GC)
mean time: 284.915 ns (0.00% GC)
maximum time: 589.474 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 323
julia> @benchmark extrema1($a)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 268.232 ns (0.00% GC)
median time: 268.824 ns (0.00% GC)
mean time: 279.133 ns (0.00% GC)
maximum time: 705.588 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 340
julia> @benchmark extrema2($a)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.250 μs (0.00% GC)
median time: 1.250 μs (0.00% GC)
mean time: 1.304 μs (0.00% GC)
maximum time: 3.680 μs (0.00% GC)
--------------
samples: 10000
evals/sample: 10
julia> @benchmark extrema3($a)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.250 μs (0.00% GC)
median time: 1.290 μs (0.00% GC)
mean time: 1.358 μs (0.00% GC)
maximum time: 5.610 μs (0.00% GC)
--------------
samples: 10000
evals/sample: 10
julia> VERSION
v"1.5.3"