JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.67k stars 5.48k forks source link

`extrema` could be faster #44606

Open LilithHafner opened 2 years ago

LilithHafner commented 2 years ago

This implementation seems to be slightly faster than extrema:

function _extrema(v)
    mn = mx = first(v)
    @inbounds for i in firstindex(v)+1:lastindex(v)
        vi = v[i]
        vi < mn && (mn = vi)
        mx < vi && (mx = vi)
    end
    mn, mx
end

@belapsed extrema(x) setup=(x=rand(Int, 10_000))
# 2.475222222222222e-6
@belapsed _extrema(x) setup=(x=rand(Int, 10_000))
# 2.0984e-6

@belapsed extrema(x) setup=(x=rand(Int, 10))
# 1.018937875751503e-8
@belapsed _extrema(x) setup=(x=rand(Int, 10))
# 7.78878878878879e-9

_Originally posted by @LilithHafner in https://github.com/JuliaLang/julia/pull/44230#discussion_r825507738_

Moelf commented 2 years ago
N5N3 commented 2 years ago

https://github.com/JuliaLang/julia/issues/31442 was mainly for float case though. (LLVM vectorlize Integer's extrema well). Some of the performance difference comes from the default pairwise_blocksize(f, op) = 1024, which might be typemax(Int) for minimum/maximum/extrema, as the result should be the same. The rest difference seems confusing. If I follows mapreduce_impl style

function __extrema(v)
    mn = mx = first(v)
    @inbounds if length(v) > 1
        mn = min(mn, v[2])
        mx = max(mx, v[2])
        for i in firstindex(v)+2:lastindex(v)
            vi = v[i]
            vi < mn && (mn = vi)
            mx < vi && (mx = vi)
        end
    end
    mn, mx
end

Then we have

julia> x = rand(Int, 4096);

julia> @btime _extrema($x);
  607.910 ns (0 allocations: 0 bytes)

julia> @btime __extrema($x);
  682.237 ns (0 allocations: 0 bytes)

julia> @btime extrema($x);
  724.627 ns (0 allocations: 0 bytes)

julia> Base.pairwise_blocksize(::Base.ExtremaMap, ::typeof(Base._extrema_rf)) = typemax(Int)

julia> @btime extrema($x);
  688.000 ns (0 allocations: 0 bytes) # quite close to `__extrema` !!!
ViralBShah commented 2 years ago

Related: #34790