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

lazy parent eltype conversion during getindex #238

Open
johnnychen94 opened this issue May 19, 2021 · 2 comments
Open

lazy parent eltype conversion during getindex #238

johnnychen94 opened this issue May 19, 2021 · 2 comments

Comments

@johnnychen94
Copy link
Member

johnnychen94 commented May 19, 2021

Because the struct definition hard-coded the eltype of the parent array:

struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N}
    parent::AA
    offsets::NTuple{N,Int}
end

whenever the wrapper OffsetArray is created, an implicity convert(AbstractArray{T, N}, parent) will be applied:

x = Int[1, 2, 3, 4]
xo = OffsetVector{Float32}(x)
parent(xo) === x # false

@btime OffsetVector{Float32}($x); # 34.555 ns (1 allocation: 96 bytes)
@btime OffsetVector($x); # 1.660 ns (0 allocations: 0 bytes)

This is an unnecessary memory allocation to me, and I believe we could relax the type to

- struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N}
+ struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N}
    parent::AA
    offsets::NTuple{N,Int}
end

and do the eltype conversion during each getindex call.

@johnnychen94 johnnychen94 changed the title lazy parent eltype conversion lazy parent eltype conversion during getindex May 19, 2021
@jishnub
Copy link
Member

jishnub commented May 19, 2021

This might open up a few surprises, since in my use I often use an OffsetArray and its parent interchangeably, especially for linear algebra usage

@johnnychen94
Copy link
Member Author

johnnychen94 commented May 19, 2021

Yes, I agree. But generally, we should move the type conversion to the caller side instead of in the callee side. https://docs.julialang.org/en/v1/manual/style-guide/#Handle-excess-argument-diversity-in-the-caller

Hence we should do

x = Float32.(get_some_vector())
xo = OffsetVector{Float32}(x)

instead of

x = get_some_vector()
xo = OffsetVector{Float32}(x)

By making the latter way lazy, we allow some room for performance tweak by saving memory usage.

We can keep this issue open until we decide to move forward to 2.0

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

No branches or pull requests

2 participants