Small union types: present and future (looking for some guidelines)

Technically, the limit is typemax(Int8), but the compiler has trouble w/ “exotic” Union types; I’d say anything over 6-8, you’ll likely run into compiler issues. And what I’m talking about here is any kind of Union types, concrete, abstract, whatever.

There are no restrictions on Ts generally; unless you’re looking for the current memory optimizations available in 0.7. The memory optimizations ares:

  1. Field types of “isbits-Union” are stored inline, with extra “selector” byte to indicate which type is stored in the actual field slot. This works by reserving a field slot big enough to hold the largest Union element type; so a field declared w/ a type of Union{Void, Int8, Int64} is going to reserve 9 bytes in the struct: the first 8 in order to hold a potential Int64, and the last byte to store a Int8 value of 0, 1, or 2, depending on if the actual value of the field is Void, Int8, or Int64, respectively.
  2. This same type of optimization has been implemented for Arrays of isbits-Union eltypes. For example, in 0.6, a Vector{Union{Void, Float32}}(10) allocated 80 bytes for elements, because Union eltypes were stored as pointers to actual values. In 0.7, that same array now allocates only 40 bytes, half as many, because the elements are now stored inline like other isbits types.

Yes, currently there is an open issue about performance issues w/ inferred Union return types. It currently boils down to the fact that when a Union type is inferred, codegen then tries to speculatively branch on the specific Union types. The problem is that the branches are inserted correctly, but within the branches, nothing ever gets inlined. This ends up causing severe performance problems if this situation happens in a hot inner loop. But as you’ve discovered, there’s a current workaround where the user has explicit code to branch on the return type anyway! In that case, inference doesn’t have to generate the Union branches, it can use them and inlines happily.

Hope that helps explain things! Let me know if anything didn’t make sense.