-
Notifications
You must be signed in to change notification settings - Fork 37
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
Non-mutating versions of pop, popfirst, etc. (#66) #68
Conversation
I can split off the |
That would be great. Thanks |
Two concerns at this point:
|
I'd be in favor of that.
Out of curiosity, what is the use case for these non-mutating functions?
Also, for If static sizing is involved, then type instability issues will make efficient use of such methods difficult. It would've been cool if this'd be fast: Base.@propagate_inbounds popfirst(x::AbstractVector) = (x[begin], @view(x[begin+1:end]))
function mysum(xorig)
x = @view(xorig[begin:end])
s = zero(eltype(x))
@inbounds @fastmath while length(x) > 0
xᵢ, x = popfirst(x)
s += xᵢ
end
s
end but it fails to vectorize. Perhaps all the checks in the creation of new views are a problem. Base.@propagate_inbounds function popfirst(x::SubArray{T,1,Vector{T},Tuple{UnitRange{Int64}},true}) where {T}
inds = first(x.indices)
xnew = SubArray{T,1,Vector{T},Tuple{UnitRange{Int64}},true}(parent(x), (first(inds)+1:last(inds),), x.offset1, x.stride1)
x[begin], xnew
end This does a little better, but still no SIMD. |
My initial goal here was to present the most generic version of those methods previously defined in StaticArrays as talking points. Here's a more opinionated breakdown:
|
* `Val` isn't supported anymore so remove related methods (e.g., `_get`) * `Static` can only be an `Int`. If either the first or last field is `Static` then eltype must but `Int`, so might as well guarantee that it is an `Int` type.
I deleted the push/pop related methods for now, as I'm not sure if it's particular helpful to have them at this point. I also added support for tuples on both the I happened upon some bugs with |
Should I move the changes to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good. If you're more or less ready, I can go ahead and merge to save you from splitting off the Static
changes.
src/ArrayInterface.jl
Outdated
Base.@propagate_inbounds function insert(collection, index, item) | ||
@boundscheck checkbounds(collection, index) | ||
ret = similar(collection, length(collection) + 1) | ||
@inbounds for i in indices(ret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would split this into separate loops. The compiler may do so automatically, but I'd rather not rely on it.
Something like:
@inbounds for i in firstindex(ret):index-1
ret[i] = collection[i]
end
@inbounds ret[index] = item
@inbounds for i in index+1:lastindex(ret)
ret[i] = collection[i-1]
end
to make sure it SIMDs well if possible.
src/static.jl
Outdated
Base.iszero(::Static{0}) = true | ||
Base.iszero(::Static) = false | ||
Base.isone(::Static{1}) = true | ||
Base.isone(::Static) = false | ||
Base.zero(::Type{T}) where {T<:Static} = Static{0}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we even want to define aliases like const Zero = Static{0}
?
I looked at the |
src/static.jl
Outdated
@@ -6,6 +6,10 @@ Use `Static(N)` instead of `Val(N)` when you want it to behave like a number. | |||
struct Static{N} <: Integer | |||
Static{N}() where {N} = new{N::Int}() | |||
end | |||
|
|||
const Zero = Static{0}() | |||
const One = Static{1}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said const Zero = Static{0}()
, but what I meant was const Zero = Static{0}
, so that we can use ::Zero
or ::One
in method signatures.
Thanks for the feedback! Hopefully, anything else? |
Some of this would be a lot cleaner if the
Static
type from #61 were available, but it's at least a start at creating generic versions for #66.