# Iteration/getindex performance of AbstractArray wrapper-types

**URL:** <https://discourse.julialang.org/t/iteration-getindex-performance-of-abstractarray-wrapper-types/53729>\
**Category:** Performance\
**Created:** [January 21, 2021, 2:59pm UTC](https://discourse.julialang.org/t/iteration-getindex-performance-of-abstractarray-wrapper-types/53729 "2021-01-21T14:59:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tchr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tchr/32/15138_2.png) [@tchr](https://discourse.julialang.org/u/tchr)\
**Post date:** [January 21, 2021, 2:59pm UTC](https://discourse.julialang.org/t/iteration-getindex-performance-of-abstractarray-wrapper-types/53729/1 "2021-01-21T14:59:11Z")

</div>

I hit what I think is a surprising performance-snag for custom array-wrapper types that subtype `AbstractArray`.

The issue is best illustrated by example: suppose I define a thin wrapper over a vector, like so:

```nohighlight
import Base: size, getindex, IndexStyle

# define a wrapper type over a vector
struct V{T} <: AbstractVector{T}
    x::Vector{T}
end
size(v::V) = size(v.x)
Base.@propagate_inbounds getindex(v::V, i::Int) = v.x[i]
IndexStyle(::Type{<:V{T}}) where T = IndexStyle(Vector{T}) # ... IndexLinear()

```

Then I would had hoped that this wrapper would perform pretty much as well as the underlying vector when I iterate over it, i.e. I had hoped the performance of each of these functions would be identical:

```nohighlight
# iterate over this wrapper directly
function f(v)
    s = zero(eltype(v))
    for vᵢ in v # <--
        s += vᵢ
    end
    return s
end
# same thing, but iterate over the underlying vector instead
function g(v)
    s = zero(eltype(v))
    for xᵢ in v.x # <--
        s += xᵢ
    end
    return s
end

```

This is true sometimes, e.g. for `Float64` element types

```nohighlight
using BenchmarkTools
v_float = V(rand(100000))

@btime f($v_float) # 117.999 μs
@btime g($v_float) # 117.999 μs --- everything performs the same; super!

```

… but, surprisingly, not for `Int` element types:

```julia
v_int = V(rand(1:10, 100000))

@btime f($v_int) # slow: 40.499 μs
@btime g($v_int) # fast: 14.399 μs

```

… what is going on here?

---

<div class="post-metadata">

**Author:** ![tchr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tchr/32/15138_2.png) [@tchr](https://discourse.julialang.org/u/tchr)\
**Post date:** [January 21, 2021, 3:35pm UTC](https://discourse.julialang.org/t/iteration-getindex-performance-of-abstractarray-wrapper-types/53729/2 "2021-01-21T15:35:08Z")

</div>

@Sukera pointed out on Slack that defining

```nohighlight
iterate(v::V, i=1) = iterate(v.x, i)

```

removes the performance penalty for the `Vector{Int}` wrapper relative to the underlying array. Needing to do this to get “full” performance is not specifically mentioned in the [AbstractArray Interfaces docs](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array); maybe it should be?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 21, 2021, 7:07pm UTC](https://discourse.julialang.org/t/iteration-getindex-performance-of-abstractarray-wrapper-types/53729/3 "2021-01-21T19:07:03Z")

</div>

I’d rather fix the core issue here than document a workaround. It is surely something to do with inlining and/or bounds check since the difference is the SIMD-ifying of the loop or not. Ah, sure enough:

[https://github.com/JuliaLang/julia/issues/39354](https://github.com/JuliaLang/julia/issues/39354)
