# Time to create Union of types in Julia 1.9.0 vs Julia 1.8.5

**URL:** <https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712>\
**Category:** Performance\
**Tags:** question, performance\
**Created:** [June 1, 2023, 8:44am UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712 "2023-06-01T08:44:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mtyogi](https://avatars.discourse-cdn.com/v4/letter/m/6f9a4e/32.png) [@mtyogi](https://discourse.julialang.org/u/mtyogi)\
**Post date:** [June 1, 2023, 8:44am UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712/1 "2023-06-01T08:44:50Z")

</div>

1. Version info
2. Julia installation. Updated v1.8.5 to v1.9.0 as follows:

```julia
]add UpdateJulia
using UpdateJulia
update_julia()

```

1. Issue

```julia
Julia Version 1.8.5
Commit 17cfb8e65e (2023-01-08 06:45 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 16 × 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, tigerlake)
  Threads: 4 on 16 virtual cores
Environment:
  JULIA_NUM_THREADS = 4
  JULIA_REVISE = auto

julia> types = [:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15];

julia> typesunion = Union{[Val{x} for x in types]...};

julia> struct obj{T<:typesunion}
         f::Int64
       end

julia> objtypesunion = Union{[obj{Val{x}} for x in types]...};

julia> @time objvec = objtypesunion[];
  0.006869 seconds (9.82 k allocations: 595.755 KiB, 94.53% compilation time)
Union{obj{Val{1}}, obj{Val{2}}, obj{Val{3}}, obj{Val{4}}, obj{Val{5}}, obj{Val{6}}, obj{Val{7}}, obj{Val{8}}, obj{Val{9}}, obj{Val{10}}, obj{Val{11}}, obj{Val{12}}, obj{Val{13}}, obj{Val{14}}, obj{Val{15}}}[]

```

The same code takes a lot of time to compile in Julia Version 1.9.0 as compared to Julia Version 1.8.5

```julia
julia> versioninfo()
Julia Version 1.9.0
Commit 8e63055292 (2023-05-07 11:25 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 16 × 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-14.0.6 (ORCJIT, tigerlake)
  Threads: 4 on 16 virtual cores
Environment:
  JULIA_NUM_THREADS = 4
  JULIA_REVISE = auto

julia> types = [:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15];

julia> typesunion = Union{[Val{x} for x in types]...};

julia> struct obj{T<:typesunion}
         a::Int64
       end

julia> objtypesunion = Union{[obj{Val{x}} for x in types]...};

julia> @time objvec = objtypesunion[]
 44.276539 seconds (48.91 M allocations: 2.915 GiB, 0.26% gc time, 100.00% compilation time)
Union{obj{Val{1}}, obj{Val{2}}, obj{Val{3}}, obj{Val{4}}, obj{Val{5}}, obj{Val{6}}, obj{Val{7}}, obj{Val{8}}, obj{Val{9}}, obj{Val{10}}, obj{Val{11}}, obj{Val{12}}, obj{Val{13}}, obj{Val{14}}, obj{Val{15}}}[]

```

The difference is not noticeable for the smaller number of types, but as the number of types increases, the compile time grows significantly.

Is this behavior expected from v1.9.0 Any suggestion to overcome this?

Other relevant links:

> [@Performance tips for Union Types](https://discourse.julialang.org/t/performance-tips-for-union-types/13928/4):
>
> That blog post is super helpful, and I hadn’t seen it yet. I wonder if it would be useful to have a blog-announce discourse category where people can post when they write a julia-related blog post? -s

> <https://github.com/JuliaLang/julia/pull/37378>
>
> This size limit should be already be imposed elsewhere (tmerge), and
> should not… actually add cost to perform the union/tuple-switching when
> there is no cartesian product to consider. This permits users to
> explicitly demand larger union products (for example, with type-asserts
> or field types) and still expect to get reliable union-splitting at any
> size in single-dispatch sites.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [June 1, 2023, 10:20am UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712/2 "2023-06-01T10:20:36Z")

</div>

While you probably don’t want such lengthy `Union` types (Union-splitting stops at 3 types, I think), this is the kind of thing you should report as an [issue](https://github.com/JuliaLang/julia/issues).

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [June 1, 2023, 12:51pm UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712/3 "2023-06-01T12:51:28Z")

</div>

As a side note, if you are frequently in need of vectors of union instances, this slack conversation about SumTypes.jl might be valuable: [Slack](https://julialang.slack.com/archives/C6FGJ8REC/p1684278109859559)

I would suggest checking out SumTypes.jl, Unityper.jl, and Expronicon.jl as libraries that might provide inspiration for your problem.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 1, 2023, 1:10pm UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712/4 "2023-06-01T13:10:29Z")

</div>

This is fixed in the upcoming 1.9.1 release already:

```julia-repl
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.9.0 (2023-05-28)
 _/ |\ __'_|_|_|\__'_| | release-1.9/a7348b7aa9d (fork: 342 commits, 199 days)
|__/ |

julia> types = [:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15];

julia> typesunion = Union{[Val{x} for x in types]...};

julia> struct obj{T<:typesunion}
         a::Int64
       end

julia> objtypesunion = Union{[obj{Val{x}} for x in types]...};

julia> @time objvec = objtypesunion[]
  0.017479 seconds (5.71 k allocations: 381.589 KiB, 96.79% compilation time)
Union{obj{Val{1}}, obj{Val{2}}, obj{Val{3}}, obj{Val{4}}, obj{Val{5}}, obj{Val{6}}, obj{Val{7}}, obj{Val{8}}, obj{Val{9}}, obj{Val{10}}, obj{Val{11}}, obj{Val{12}}, obj{Val{13}}, obj{Val{14}}, obj{Val{15}}}[]

```

---

<div class="post-metadata">

**Author:** ![mtyogi](https://avatars.discourse-cdn.com/v4/letter/m/6f9a4e/32.png) [@mtyogi](https://discourse.julialang.org/u/mtyogi)\
**Post date:** [June 2, 2023, 6:38am UTC](https://discourse.julialang.org/t/time-to-create-union-of-types-in-julia-1-9-0-vs-julia-1-8-5/99712/5 "2023-06-02T06:38:35Z")

</div>

Thank you all for the solutions and suggestions.
