Skip to content

Add a benchmark involving realistic code that creates large unions #240

@AlexWaygood

Description

@AlexWaygood

Code that creates large unions (explicitly or implicitly) is known to be hard for type checkers to analyze in a performant way. Both mypy and pyright have had lots of issues regarding performance for these, and both have implemented several optimizations to deal with them. We should add at least one benchmark (probably several) that measures how we do on this.

Common themes that come up in this area are:

  • Unions involving Literal types (Literal[1, 2, 3] desugars to Literal[1] | Literal[1] | Literal[3] from the type checker's perspective, so "medium-sized Literal types" quickly end up creating huge unions)

  • Enums. A similar issue to Literal types. If you have an enum like this:

    class A(enum.Enum):
        X = 1
        Y = 2
        Z = 3

    Then in some cases, x: A can desugar to x: Literal[A.X] | Literal[A.Y] | Literal[A.Z]

  • Pydantic. Pydantic uses some big unions, and features in performance bug reports in both the mypy and pyright issue trackers.

  • Unions involving protocols

  • Unions involving recursive type aliases

  • Unions involving TypedDicts

References

Here are some references that are worth looking at (and from which we might be able to derive benchmarks). The great thing about all of these is that they are performance issues that we know real users encountered when their type checker was checking real code. I've tried to exclude anything specific to recursive type aliases, since that feels somewhat out of scope for this issue:

Mypy

Pyright

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePotential performance improvementset-theoretic typesunions, intersections and moretestingRelated to testing ty itself

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions