Skip to content

Potential performance improvements to Base minimum and maximum on arrays of integers #36412

@brenhinkeller

Description

@brenhinkeller

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 Arrays, 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 Floats, except for arrays of fewer than 1000 elements.

Float64_minimum.pdf

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    foldsum, maximum, reduce, foldl, etc.performanceMust go faster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions