Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conversion in getindex #26615

Merged

Conversation

haampie
Copy link
Contributor

@haampie haampie commented Mar 26, 2018

Fixes #26608 (all edge cases of it) and improves performance for the @inbounds case a lot.

Note that using @inbounds will now return garbage results when going out of bounds, whereas it previously would throw a conversion error. Should be fine.

@haampie
Copy link
Contributor Author

haampie commented Mar 26, 2018

Right, didn't think about ranges of rationals. Maybe just specialize this implementation on BitIntegers and Bools then?

Side-note: the test that fails seems odd. A = rand(1//1:5//5, 4,3) is just a matrix with all elements 1//1 since 1//1 == 5//5.

@haampie haampie force-pushed the fix-range-conversion-in-getindex branch from 3860d1e to d7bd85a Compare March 26, 2018 12:10
@haampie haampie force-pushed the fix-range-conversion-in-getindex branch from d7bd85a to 01dd920 Compare March 26, 2018 12:15
const OverflowSafe = Union{Bool,Int8,Int16,Int32,Int64,Int128,
UInt8,UInt16,UInt32,UInt64,UInt128}

function getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe}
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just use Union{Bool, Base.BitInteger} for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was trying that, but it turns out BitInteger is defined a couple includes away in int.jl, and when I tried moving the constants to a separate file int_types.jl, I broke stuff without very useful feedback from make. It's worth defining these types a bit earlier, because other places redefine them as well!

@@ -473,11 +473,23 @@ end

## indexing

_in_unit_range(v::UnitRange, val, i::Integer) = i > 0 && val <= v.stop && val >= v.start
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, I totally believe that this is faster — bounds checks are very friendly to branch prediction and when they miss, well, we really don't care about performance anymore.

@mbauman
Copy link
Sponsor Member

mbauman commented Mar 26, 2018

@nanosoldier runbenchmarks(ALL, vs = ":master")

I'm not sure if we have any tests that index into UnitRanges without bounds checks @inbounds, but I'm curious. If Nanosoldier fails this isn't terribly crucial. Maybe you could share your spot-perf checks?

@haampie
Copy link
Contributor Author

haampie commented Mar 26, 2018

Broadcasting example:

@benchmark v[1001 : 5096] .= Int32(-2048):Int32(2047) setup = (v = Vector{Int32}(undef, 10000))

Before: 4.075 μs
After: 1.359 μs

Further issue #26608 (comment) has an example where bounds checking is 2x faster.

@haampie
Copy link
Contributor Author

haampie commented Mar 26, 2018

Same tricks with value % T and changing & -> && makes indexing of StepRange and Base.OneTo faster as well :). So I'll expand and tidy this PR a bit.

Fixing #26623 would make bounds checking for ranges slower unfortunately.

@KristofferC
Copy link
Sponsor Member

@nanosoldier runbenchmarks(ALL, vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan

@KristofferC
Copy link
Sponsor Member

Is this good to go?

@haampie
Copy link
Contributor Author

haampie commented Jun 26, 2018

I think yes

@KristofferC KristofferC merged commit c500caa into JuliaLang:master Jun 26, 2018
jrevels pushed a commit that referenced this pull request Jul 2, 2018
* Test more out of bounds errors for the UnitRange type

* Do the conversion in getindex of UnitRange only when returning
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants