-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
While trying to time some other things I recently noticed that a naive @inbounds for loop minimum function, e.g.
function f_minimum(A::Array{<:Integer})
result = A[1]
@inbounds for i=2:length(A)
if A[i] < result
result = A[i]
end
end
return result
end
seems to significantly (up to a factor of five) outperform Base.minimum on arrays of integers:
julia> x = rand(Int, 10_000);
julia> using BenchmarkTools
julia> @btime minimum($x)
5.440 μs (0 allocations: 0 bytes)
-9222934526579860823
julia> @btime f_minimum($x)
1.578 μs (0 allocations: 0 bytes)
-9222934526579860823
This holds true over all the array sizes I tested, and for both Int s and UInt s from 8 to 64 bits.
Int64_minimum.pdf
UInt64_minimum.pdf
If the assumption I made about the array indices (to avoid redundantly comparing the first element to itself) is considered bad form even for plain Array
s, then you can still obtain a substantial performance improvement over Base with something more along the lines of
function f_minimum(A)
result = first(A)
for x in A
if x < result
result = x
end
end
return result
end
Notably, it's much harder to beat Base for Float
s, except for arrays of fewer than 1000 elements.
Thanks to @giordano @mcabbott @jakobnissen for discussion on Slack. If there's some consensus on the right way to proceed I'd be happy to try to make a PR, if the correct solution isn't too far out of my depth.