# Warntype when accessing Vector{AbstractType}

**URL:** <https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863>\
**Category:** New to Julia\
**Created:** [March 14, 2019, 1:19pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863 "2019-03-14T13:19:40Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 14, 2019, 1:19pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/1 "2019-03-14T13:19:40Z")

</div>

hello, I could not resolve the problem like the following: where the field in a `struct` is a `Vector` of abstract type, warntype would be triggered when accessing the content of the vector. Any help would be appreciated. thanks.

```julia
struct Test
    v::Vector{Real}

    function Test(a::Real, b::Real)
        ab = Vector{Real}(undef, 2)
        ab[1] = a
        ab[2] = b
        new(v)
    end
end

function fun(obj::Test)
    println(obj.v[1])
    println(obj.v[2])
end

obj = Test(0, 1.1)
fun(obj)
@code_warntype fun(obj)

julia> @code_warntype fun(obj)
Body::Nothing
1 ─ %1 = (Base.getfield)(obj, :v)::Array{Real,1}
│ %2 = (Base.arrayref)(true, %1, 1)::Real
│ (Main.println)(%2)
│ %4 = (Base.getfield)(obj, :v)::Array{Real,1}
│ %5 = (Base.arrayref)(true, %4, 2)::Real
│ %6 = (Main.println)(%5)::Core.Compiler.Const(nothing, false)
└── return %6

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 14, 2019, 1:23pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/2 "2019-03-14T13:23:29Z")

</div>

in fact, I tried to define a “barrier” for it, but at the end the barrier itself has warntype also:

```julia
function barrier_v1(v::Vector{Real})::Int64
    v[1]
end

julia> barrier_v1(obj.v)
0

julia> @code_warntype barrier_v1(obj.v)
Body::Int64
1 ─ %1 = Main.Int64::Core.Compiler.Const(Int64, false)
│ %2 = (Base.arrayref)(true, v, 1)::Real
│ %3 = (isa)(%2, Int64)::Bool
└── goto #3 if not %3
2 ─ %5 = π (%2, Int64)
└── goto #4
3 ─ %7 = (Base.convert)(%1, %2)::Any
└── goto #4
4 ┄ %9 = φ (#2 => %5, #3 => %7)::Any
│ (Core.typeassert)(%9, %1)
│ %11 = π (%9, Int64)
└── return %11

```

---

<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 14, 2019, 1:30pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/3 "2019-03-14T13:30:49Z")

</div>

That’s how it is, see Performance Tips of the manual.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 14, 2019, 1:37pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/4 "2019-03-14T13:37:42Z")

</div>

so, the only workaround is to define parametric type?

---

<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 14, 2019, 1:45pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/5 "2019-03-14T13:45:34Z")

</div>

Well, you could do:

```julia
struct Test
  v::Vector{<:Real}
...
end

```

then you can put, say, a `Vector{Int}` into `Test.v` and then a function barrier will work. But if you have a `Vector{Real}` then a function barrier cannot work because after the barrier it is still an abstract eltype.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 14, 2019, 2:00pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/6 "2019-03-14T14:00:55Z")

</div>

hm… `Vector{<:Real}` not work because the each eltype could be different…

parametric type is fine, except when the number of (dynamically determined) types are **unknown**.

what I mean is, _if the number is known_, we can define like: (in this example, the number is 2)

```julia
struct Test2{S<:Real, T<:Real}
    v1::S
    v2::T

    function Test2(a::SS, b::TT) where {SS<:Real, TT<:Real}
        new{SS, TT}(a, b)
    end
end

```

however, things get complicated when the “number” is not known, in such case rather than passing `a` and `b`, we would like to pass a `Vector{Real}` into the constructor, and the **number of “parametric type” would equal the length of the vector** … how to do that???

---

<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:** [March 14, 2019, 2:08pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/7 "2019-03-14T14:08:26Z")

</div>

You can use a tuple instead of a vector. But in this case it sounds like it’d be okay to have a type instability here. If you want to dynamically collect a group of things together — and you don’t know ahead of time what types they’ll be — then trying to communicate those types to Julia ahead of time will be challenging.

Type instabilities are just fine in situations like this. You don’t need absolutely every function you write to have a “clean” code\_warntype.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 14, 2019, 3:32pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/8 "2019-03-14T15:32:26Z")

</div>

> [@mbauman](#):
>
> You can use a tuple instead of a vector.

could you show an example that uses a tuple would give better type stability than vector? thanks.

> [@mbauman](#):
>
> You don’t need absolutely every function you write to have a “clean” code\_warntype.

why? isn’t each warntype means slow execution?

---

<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 14, 2019, 3:39pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/9 "2019-03-14T15:39:28Z")

</div>

> [@tomtom](#):
>
> isn’t each warntype means slow execution?

Is this in a performance critical section of your code? Did you profile it? If not, just leave it. If it is, it will be reasonably tricky to get fast because operating on a bunch of different things is slow. Except if it is just a small union of different types, then you should encode that. Reference in [How to tell if a type is an efficient small type union?](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829) might help.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 14, 2019, 6:46pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/10 "2019-03-14T18:46:16Z")

</div>

> [@tomtom](#):
>
> why? isn’t each warntype means slow execution?

Not necessarily. There is certainly a cost to type-unstable code, but it may not have a significant effect on the overall speed of your code. The key thing to remember is that once you pass a value into a function, no matter whether Julia inferred the type of that value or not, the function will be equally fast.

For example, let’s say your code looks like

```julia
for i in x
  f(i)
end

```

if your `x` is a `Vector{Real}`, then there will be some time spent at each iteration of the loop looking up the actual type of each element `i`. But the speed of executing `f(i)` will be _exactly the same_. So you can approximate the time spent in that loop as:

```julia
time_abstract_loop = (time_type_lookup + time_f_i) * length(x)

```

If your `x` is a container of concrete elements, like `Vector{Float64}`, then that type lookup time goes away, so the time in the loop can be approximated as:

```julia
time_concrete_loop = (time_f_i) * length(x)

```

The slowdown from type instability is the ratio of those two times:

```julia
slowdown = time_abstract_loop / time_concrete_loop 
         = (time_type_lookup + time_f_i) / time_f_i

```

I usually guess about 100ns for `time_type_lookup`, so if your `time_f_i` is just a few nanoseconds, then that slowdown can be _huge_. But if your `time_f_i` is large, then you should expect to see `slowdown` very close to 1, meaning the overall speed of your code won’t be affected noticeably.

---

<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:** [March 14, 2019, 7:52pm UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/11 "2019-03-14T19:52:49Z")

</div>

> [@rdeits](#):
>
> There is certainly a cost to type-unstable code, but it may not have a significant effect on the overall speed of your code

I just also want to emphasize that there’s a big advantage to type-unstable code — it can perform many dynamic behaviors that aren’t possible (or easy) otherwise. Don’t be scared of type instabilities unless they’re actually appearing within your hot loop as @rdeits nicely describes.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [March 15, 2019, 10:35am UTC](https://discourse.julialang.org/t/warntype-when-accessing-vector-abstracttype/21863/12 "2019-03-15T10:35:09Z")

</div>

\<post deleted: it was answered above, sorry…\>
