# How to implement efficient custom array

**URL:** https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189
**Category:** Performance
**Created:** [March 22, 2019, 10:07am UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189 "2019-03-22T10:07:32Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [March 22, 2019, 10:07am UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189/1 "2019-03-22T10:07:32Z")

</div>

How to implement a custom StridedArray or DenseArray?

I have some C-code which returns a pointer to an array, which I can wrap using `unsafe_wrap`. I need to build a custom array-implementation, but operations on this custom array is a lot slower than on the array (wrapped or not):

```julia
abstract type AbstractFooArray{T,N} <: DenseArray{T,N}
end

mutable struct FooArray{T,N} <: AbstractFooArray{T,N}
    array::DenseArray{T,N}
end

Base.IndexStyle(::Type{<:AbstractFooArray{T,N}}) where {T,N} = IndexLinear()
Base.getindex(a::AbstractFooArray{T,N}, i::Int) where {T,N} = a.array[i]
Base.setindex!(a::AbstractFooArray{T,N}, v, i::Int) where {T,N} = a.array[i] = v

Base.size(a::AbstractFooArray{T,N}) where {T,N} = size(a.array)

#Base.strides(a::AbstractFooArray{T,N}) where {T,N} = strides(a.array)
#Base.unsafe_convert(::Type{Ptr{T}}, a::AbstractFooArray{T,N}) where {T,N} = unsafe_convert(Ptr{T}, a.array)
#Base.has_fast_linear_indexing(a::AbstractFooArray{T,N}) where {T,N} = true

a = zeros(UInt8, (3, 2448, 2048));
b = unsafe_wrap(Array, pointer(a), size(a));

a_f = FooArray(a)
b_f = FooArray(b)

```

```julia
@time sum(a)
@time sum(b)

```

```julia
  0.002121 seconds (4 allocations: 160 bytes)
  0.002241 seconds (4 allocations: 160 bytes)

```

```julia
@time sum(a_f)
@time sum(b_f)

```

```julia
  0.562584 seconds (16 allocations: 400 bytes)
  0.546441 seconds (16 allocations: 400 bytes)

```

The reported numbers are after compilation warm-up (second run).

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [March 22, 2019, 10:11am UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189/2 "2019-03-22T10:11:36Z")

</div>

There might be other things but a biggy is that `DenseArray` is an abstract type and thus having a type field with that type is slow. See performance tips in the docs.

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [March 22, 2019, 11:59am UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189/3 "2019-03-22T11:59:31Z")

</div>

Thanks - that helped a lot - brought the gap to a factor ~ 5:

```julia
  0.002038 seconds (4 allocations: 160 bytes)
  0.002234 seconds (4 allocations: 160 bytes)

```

```julia
  0.010350 seconds (4 allocations: 160 bytes)
  0.009492 seconds (4 allocations: 160 bytes)

```

```julia

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [March 22, 2019, 12:19pm UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189/4 "2019-03-22T12:19:10Z")

</div>

Maybe you don’t need a custom array type? You can create a Julia array that is backed by C-allocated memory. Unless you need different behavior a new type is unnecessary.

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [March 23, 2019, 7:41am UTC](https://discourse.julialang.org/t/how-to-implement-efficient-custom-array/22189/5 "2019-03-23T07:41:27Z")

</div>

True, but in this case I would like to add reference counting with a custom dispose function to enable re-use of large arrays (returning it to a pool of arrays from which it can be re-used):  
[https://github.com/IHPSystems/ResourcePools.jl/tree/feature/pooled\_resource/src](https://github.com/IHPSystems/ResourcePools.jl/tree/feature/pooled_resource/src)
