While union type is very convenient in some cases, I am wondering what is the performance impact of this feature.
Does it introduce extra boxing/unboxing operations? Is it more efficient than a class hierarchy?
Is there any documentation about the underlying implementation of union type? I am keen to learn more about it.
Many thanks in advance!
Union types are erased to their upper bound, so there’s no boxing (except where necessary).
You can use
:settings -Vprint:erasure in the REPL to show the output of the “erasure” phase, which happens “just” before the java bytecode is emitted.
Here are some examples:
def f(x: String | Seq[String]) = () /* becomes f(x: java.lang.Object) */
def f(x: Int | Long) = () // becomes f(x: java.lang.Object) too, so here the parameter is boxed
class C1 extends Parent
class C2 extends Parent
def f(x: C1 | C2) = () // becomes f(x: Parent)
edit: To conclude, choosing to use union types or not is not a matter of performance. It depends on what you’re trying to achieve Using union types allows to put more restriction on the types in a very handy way.
Would this then have implications if compiled code using union types is used in a library? Could the library consumer pass arbitrary objects to a function expecting a String or sequence of them?
If the library was consumed by Java, then they could pass arbitrary objects. From another Scala program, no - union types will be enforced