How to implement fast range reads for my custome-defined array?



I need to implement my own array type underlying which is still a Vector, but reading/writing to it is much much slower than reading/writing the vanilla Julia array. I can reproduce the problem in this simple program below. Could someone see what I did wrong?

type MyArray{T, N} <: AbstractArray{T, N}
    MyArray(dims::NTuple{N, Int64}) = length(dims) > 0 ?
        new(Vector{T}(reduce(*, [dims...])), dims) :
        new(Vector{T}(), dims)

function Base.linearindexing(::MyArray)
    return Base.LinearFast()

function Base.size(array::MyArray)
    return array.dims

function Base.getindex(array::MyArray, i::Int)
    return array.values[i]

function Base.setindex!(array::MyArray, v, i::Int)
    array.values[i] = v

function Base.similar{T, N}(array::MyArray{T, N}, ::Type{T}, dims::NTuple{N, Int64})
    return MyArray{T, N}(dims)

c = MyArray{Float64, 2}((100, 3000))
@time for i = 1:3000
    d = c[:, i]

a = rand((100, 3000))
@time for i = 1:3000
    b = a[:, i]

According to the output of @time, it seems my implementation causes a lot more memory allocation than Julia’s. How may I fix it?

4.525247 seconds (10.35 M allocations: 228.042 MB, 3.78% gc time)
0.025936 seconds (28.96 k allocations: 3.634 MB)


Your dims::Tuple field is not concretely typed. Perhaps it should be ::NTuple{N, Int}?.

Also, it is unikely that you want to have that type be mutable so change to immutable (or just struct in the new syntax). Note, making the type non mutable does not mean you cannot mutate the values in the values field.


Thanks! This solved my problem!