# Sort three numbers

So, I wrote this function to sort three numbers in Julia. Any feedback on readability, performance, and Julian-ness would be appreciated.

function sort_asc(a, b, c)
# defined in function so as not to overwrite Base.minmax
minmax(x, y) = ifelse(x < y, (x, y), (y, x))

l1, h1 = minmax(a, b)
lo, h2 = minmax(l1, c)
md, hi = minmax(h1, h2)

return lo, md, hi
end

• There's no need to swap x and y if they're equal, so I'd prefer less-or-equal instead of less-than. Jul 19 at 13:37

As it turns out

function sort_asc(a, b, c)
l1, h1 = minmax(a, b)
lo, h2 = minmax(l1, c)
md, hi = minmax(h1, h2)
return lo, md, hi
end


results in the exact same native assembly instructions on my machine (compared to the branchless version). So, given its greater simplicity, I think this is the best version so far.

Here are comparisons to other implementations

function sort3(a, b, c)
l1, h1 = minmax(a, b)
lo, h2 = minmax(l1, c)
md, hi = minmax(h1, h2)
return lo, md, hi
end

@inline minmax_nb(x, y) = ifelse(isless(x, y), (x, y), (y, x))

function sort3_nb(a, b, c)
l1, h1 = minmax_nb(a, b)
lo, h2 = minmax_nb(l1, c)
md, hi = minmax_nb(h1, h2)
return lo, md, hi
end

function sort3_koen(a, b, c)
lo, md = minmax(a, b)
if md > c
hi = md
lo, md = minmax(lo, c)
else
hi = c
end

return lo, md, hi
end


Here is the benchmark code

using BenchmarkTools

function map_sort3!(f::F, out, data) where F
@inbounds for i in eachindex(out, data)
a, b, c = data[i]
out[i]  = f(a, b, c)
end
end

for f in [sort3, sort3_nb, sort3_koen]
@btime map_sort3!(\$f, out, data) setup=begin
data = [ntuple(i -> rand(Int), 3) for _ in 1:10_000]
out = similar(data)
end evals=1
end


And here are the results on my machine:

sort3       :  17.286 μs (0 allocations: 0 bytes)
sort3_nb    :  17.624 μs (0 allocations: 0 bytes)
sort3_koen  :  21.776 μs (0 allocations: 0 bytes)


I'd expect this to be marginally faster:

(lo,md) = minmax(a,b)
if md > c
hi = md
(lo,md) = minmax(lo,c)
else
hi = c


I don't know where this sits in the scale of Julianesquinness since I'm not familiar with Julia (not even sure if my "if-else" adheres to its syntax, but the intention should be clear).