Skip to content

Unexpected slowness initializing large array with discriminated union constituentsΒ #42522

Closed
@RyanCavanaugh

Description

@RyanCavanaugh

Bug Report

πŸ”Ž Search Terms

union array initialization performance

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried since 3.3. No meaningful perf changes were observed depending on TS version

⏯ Playground Link

Too large; here's a spreadsheet

https://docs.google.com/spreadsheets/d/1mk6oEwD8YrycBeSNDX4gaM9rxVULgNB_ljAGrQkned8/edit?usp=sharing

πŸ’» Code

Instead of 3 constituents, the actual repro has 500 (this is approximately the number found in the real repro) for each example.

Setup:

type Action =
 | Action1
 | Action2
 | Action3;

type Action1 = { type: 1, payload: number };
type Action2 = { type: 2, payload: number };
type Action3 = { type: 3, payload: number };

πŸ™ Actual behavior

Checking with --skipLibCheck --strict --extendedDiagnostics, we see some undesirable perf variances here.

The "const" version checks in 0.6s:

const p1: Action = { type: 1, payload: 42 };
const p2: Action = { type: 2, payload: 42 };
const p3: Action = { type: 3, payload: 42 };

The "basic array" version checks in 1.0s:

const test: Action[] = [
    { type: 1, payload: 42 },
    { type: 2, payload: 42 },
    { type: 3, payload: 42 }
];

The "poisoned array" version (which is closest to the customer repro) checks in 1.3s:

declare const a: Action;
const test: Action[] = [
    a,
    { type: 1, payload: 42 },
    { type: 2, payload: 42 },
    { type: 3, payload: 42 }
];

The "array with extra target" version checks in 1.6s:

const test: Array<Action | string> = [
    { type: 1, payload: 42 },
    { type: 2, payload: 42 },
    { type: 3, payload: 42 }
];

The "unannotated array" version checks in 0.07s (obviously not a target, but shows that these perf numbers aren't cause by "other work):

const test = [
    { type: 1, payload: 42 },
    { type: 2, payload: 42 },
    { type: 3, payload: 42 }
];

πŸ™‚ Expected behavior

All of the array cases should be checked approximately as fast as the const version, not >2x slower.

Other notes:

  • Using a string discriminant in place of number doesn't change anything
  • The original repro is even larger
  • Timing numbers are on my i7-10700K (i.e. a very fast computer by 2021 standards)

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: PerformanceReports of unusually slow behavior

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions