← Back to context

Comment by samus

2 years ago

> in JS, a type must NOT be a union of multiple types if you want it to optimize)

Does that mean that tagged unions (functional programming-style data types) are inherently slow in JavaScript? Maybe there is a way for the TypeScript compiler to pass pragmas (via comments in generated code) to the interpreter.

They can have pitfalls is a better way to think about it. Inheritance has a similar penalty.

The potential problem is that JS engines only see the ‘shape’ of an object. That is the members and member order. Which is slightly more strict that TS’s structural types where order doesn’t matter. So union variants and subtypes are each different shapes if they have different members or member order.

Shapes are important for function calls. Objects property access is optimised based on the number of ‘shapes’ that have been seen. Into the following:

Monomorphic - It’s seen only 1 shape and can access the properties by offset directly.

Polymorphic - A small inline cache of several shapes. Access is a lookup into this. Slightly slower.

Megamorphic - A lookup into a global table. This is a performance cliff.

So if you have lots of functions that take a tagged union or base class *and at runtime* they see lots of different types passed in *and this is in a hot path* they can be a problem.