Skip to content

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

Closed
@MasonProtter

Description

@MasonProtter

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.

Metadata

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