Skip to content

convert: for arrays, copy or view? #20826

@timholy

Description

@timholy

The docstring for convert is wonderfully explicit about providing details about the underlying assumptions in many cases, but I've found one that isn't yet covered. convert(T, x) has the behavior that if x already has type T, we just return x. But for AbstractArrays, things get more complicated:

julia> A = rand(3,5)
3×5 Array{Float64,2}:
 0.324103  0.45017   0.469432  0.382722  0.241098 
 0.336333  0.481648  0.165303  0.616973  0.0452947
 0.567737  0.964775  0.82846   0.300232  0.140285 

julia> pointer(A)
Ptr{Float64} @0x00007fad96e33ba0

julia> pointer(convert(Array, A))
Ptr{Float64} @0x00007fad96e33ba0

julia> S = view(A, :, :)
3×5 SubArray{Float64,2,Array{Float64,2},Tuple{Colon,Colon},true}:
 0.324103  0.45017   0.469432  0.382722  0.241098 
 0.336333  0.481648  0.165303  0.616973  0.0452947
 0.567737  0.964775  0.82846   0.300232  0.140285 

julia> pointer(convert(Array, S))
Ptr{Float64} @0x00007fad970d8e20

In the first case we didn't copy, in the second we did. Often there is no choice but to copy, for example if we had defined S = view(A, 1:2, 1:3); however, in cases like view(A, :, :) it would be possible to return the original without making a copy (and it wouldn't violate type-stability).

An even more intermediate case comes from array types like

struct MyArray{T,N} <: AbstractArray{T,N}
    data::Array{T,N}
end

For this type, convert(Array, A::MyArray) could always return A.data directly. But is this advisable? Or should it be a copy any time typeof(A) != T?

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs decisionA decision on this change is needed

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions