# How to tell if a type is an efficient small type union?

**URL:** https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829
**Category:** General Usage
**Created:** [December 19, 2018, 1:48pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829 "2018-12-19T13:48:26Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [December 19, 2018, 1:48pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/1 "2018-12-19T13:48:27Z")

</div>

`Vector{Union{Missing, Int}}` is efficiently represented, but `Vector{Union{Int, Float64}}` isn’t. Is there a predicate to distinguish between the two, similar to `isconcretetype`?

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 19, 2018, 2:32pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/2 "2018-12-19T14:32:45Z")

</div>

How are you determining is/isnot “efficiently represented”?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [December 19, 2018, 3:12pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/3 "2018-12-19T15:12:42Z")

</div>

> [@cstjean](#):
>
> but `Vector{Union{Int, Float64}}` isn’t

I was under the impression that the [optimizations for `isbits` `Union`s](https://docs.julialang.org/en/v1/devdocs/isbitsunionarrays/) apply to `Vector{Union{Int, Float64}}` too, since both `Int` and `Float64` are bits types. Is this not the case?

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 19, 2018, 3:19pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/4 "2018-12-19T15:19:35Z")

</div>

It is the case. Missing and Nothing behave a little differently in those Unions if they are present as `missing` or `nothing` in a vector (see below) – but not if they are in the Union type and not present in the vector. That’s why I asked “How is this being determined”?

```julia
julia> Base.summarysize(Union{Missing,Int32}[1, 2])
56

julia> Base.summarysize(Union{Missing,Int32}[1, missing])
52

julia> Base.summarysize(Union{Nothing,Int32}[1, nothing])
52

```

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [December 19, 2018, 4:13pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/5 "2018-12-19T16:13:02Z")

</div>

TIL, thank you for pointing me to the docs. So I suppose it boils down to checking if all the unioned types are isbits?

Maybe the more straight-forward question is: how do I know if `Array{T}` is represented internally as an array of pointers?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [December 19, 2018, 4:45pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/6 "2018-12-19T16:45:07Z")

</div>

> [@cstjean](#):
>
> how do I know if `Array{T}` is represented internally as an array of pointers?

You mean how whether it should be, or to introspect what happens for a particular `T` in practice?

I think the current situation is that for the union of two (or more?) bits types, it is guaranteed to be represented efficiently, but this is an implementation detail and may be expanded later on.

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [December 19, 2018, 5:00pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/7 "2018-12-19T17:00:19Z")

</div>

Right, but for context, I’d like to fix this performance warning: [Spurious warning about concrete types · Issue #287 · JuliaMath/Interpolations.jl · GitHub](https://github.com/JuliaMath/Interpolations.jl/issues/287)

---

<div class="post-metadata">

### Author: ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)
#### Post date: [December 19, 2018, 5:29pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/8 "2018-12-19T17:29:06Z")

</div>

`Base.isbitsunion(T)`

---

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [December 19, 2018, 8:18pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/9 "2018-12-19T20:18:41Z")

</div>

It also seems, that unions are only optimized if they are over less then five types:

```julia
julia> f(a) = first(a)/2
f (generic function with 1 method)

julia> types = filter(isbitstype,subtypes(Signed))
5-element Array{Any,1}:
 Int128
 Int16 
 Int32 
 Int64 
 Int8  

julia> using BenchmarkTools

julia> for i in eachindex(types)
           T = Union{types[1:i]...}
           @show T
           @show Base.isbitsunion(T)
           arr = T[one(first(types))]
           println(@btime f($arr))
       end
T = Int128
Base.isbitsunion(T) = false
  7.103 ns (0 allocations: 0 bytes)
0.5
T = Union{Int128, Int16}
Base.isbitsunion(T) = true
  9.050 ns (0 allocations: 0 bytes)
0.5
T = Union{Int128, Int16, Int32}
Base.isbitsunion(T) = true
  9.349 ns (0 allocations: 0 bytes)
0.5
T = Union{Int128, Int16, Int32, Int64}
Base.isbitsunion(T) = true
  8.787 ns (0 allocations: 0 bytes)
0.5
T = Union{Int128, Int16, Int32, Int64, Int8}
Base.isbitsunion(T) = true
  33.701 ns (2 allocations: 48 bytes)
0.5

```

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 19, 2018, 9:01pm UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/10 "2018-12-19T21:01:01Z")

</div>

What is an efficient way to determine the number of constituents in a Union of concrete types? Or, better yet, get them as a tuple quickly.

just found the answer in a post by TPapp : Base.uniontypes(x)

how about

```julia
isfastunion(::Type{T}) where {U,T<:Union{U}} =
    Base.isbitsunion(T) && length(Base.uniontypes(T)) < 5

```

---

<div class="post-metadata">

### Author: ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)
#### Post date: [December 20, 2018, 5:48am UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/11 "2018-12-20T05:48:08Z")

</div>

> [@jw3126](#):
>
> It also seems, that unions are only optimized if they are over less then five types:

Why is that?

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 20, 2018, 8:45am UTC](https://discourse.julialang.org/t/how-to-tell-if-a-type-is-an-efficient-small-type-union/18829/12 "2018-12-20T08:45:35Z")

</div>

because if not `5` then 4or6or6ish – my guess:  
it has to be \< lbits\_ina\_byte for bitset speed without too much typeish mem overhead (which would be slowing overall). As we do not yet know how best to utilize the possibles, it was deemed smart to hold a bit or two in reserve while the better use comes to the fore. .there is more involved than altering a constant. tbd.
