Skip to content

view(::Memory, ::UnitRange) should not create a Vector #54768

Closed

Description

I wasn't around to complain about #53896, but I think that PR was a bad idea. That PR made view worse at doing the regular job that view is used for, and repurposes it for a different job.

  1. This now makes it so that generic functions that call
view(::AbstractVector, ::UnitRange)

might end up doing an unnecessary allocation depending on if you get a Memory (because Vector is a mutable struct). This means that any generic function that takes a view at every iteration of a loop is in danger of accidentally performing N allocations if it is passed a Memory. For example:

function f(v)
    s = 0.0
    for i  firstindex(v):lastindex(v)-1
        s += sum(@view v[i:i+1])
    end
    s
end;

julia> let m = Memory{Float64}(undef, 10000) .= 1
           @btime f($m)
       end
  43.232 μs (9999 allocations: 312.47 KiB)
19998.0

julia> let v = Vector{Float64}(undef, 10000) .= 1
           @btime f($v)
       end
  10.129 μs (0 allocations: 0 bytes)
19998.0
  1. If you actually wanted a regular SubArray{<:Memory}, you cannot use view for that and instead need to call the SubArray constructor directly

  2. The only reason you'd want this to return a Vector instead of a SubArray is if you wanted to push! or otherwise resize the result, but it's generally not good practice to encourage people to write push!(view(m, idxs), x) because that'd normally error.


I propose we remove this method before 1.11 drops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    arrays[a, r, r, a, y, s]

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions