You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Specialize findlast for integer AbstractUnitRanges and StepRanges (#54902)
For monotonic ranges, `findfirst` and `findlast` with `==(val)` as the
predicate should be identical, as each value appears only once in the
range. Since `findfirst` is specialized for some ranges, we may define
`findlast` as well analogously.
On v"1.12.0-DEV.770"
```julia
julia> @Btime findlast(==(1), $(Ref(1:1_000))[])
1.186 μs (0 allocations: 0 bytes)
1
```
This PR
```julia
julia> @Btime findlast(==(1), $(Ref(1:1_000))[])
3.171 ns (0 allocations: 0 bytes)
1
```
I've also specialized `findfirst(iszero, r::AbstractRange)` to make this
be equivalent to `findfirst(==(0), ::AbstractRange)` for numerical
ranges. Similarly, for `isone`. These now take the fast path as well.
Thirdly, I've added some `convert` calls to address issues like
```julia
julia> r = Int128(1):Int128(1):Int128(4);
julia> findfirst(==(Int128(2)), r) |> typeof
Int128
julia> keytype(r)
Int64
```
This PR ensures that the return type always corresponds to `keytype`,
which is what the docstring promises.
This PR also fixes
```julia
julia> findfirst(==(0), UnitRange(-0.5, 0.5))
ERROR: InexactError: Int64(0.5)
Stacktrace:
[1] Int64
@ ./float.jl:994 [inlined]
[2] findfirst(p::Base.Fix2{typeof(==), Int64}, r::UnitRange{Float64})
@ Base ./array.jl:2397
[3] top-level scope
@ REPL[1]:1
```
which now returns `nothing`, as expected.
0 commit comments