-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Unexpected slowness initializing large array with discriminated union constituents #42522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Several costly operations are at play in various forms in the examples. const p1: Action = { type: 1, payload: 42 };
const p2: Action = { type: 2, payload: 42 };
const p3: Action = { type: 3, payload: 42 };
... The first expensive operation here is assignability checking between each object literal type and the Second issue is contextual type discrimination. Every time we ask for a contextual type on the object literal side, we end up filtering the const test: Action[] = [
{ type: 1, payload: 42 },
{ type: 2, payload: 42 },
{ type: 3, payload: 42 },
...
]; Here we add a third expensive operation, subtype reduction. Every object literal type ends up being structurally related to every other object literal type--without actually reducing anything. declare const a: Action;
const test: Action[] = [
a,
{ type: 1, payload: 42 },
{ type: 2, payload: 42 },
{ type: 3, payload: 42 },
...
]; Adding an extra target causes the source and target union types to have different numbers of constituents, so we defeat an optimization we have where we first relate constituents at the same index in both unions when they're the same size. const test = [
{ type: 1, payload: 42 },
{ type: 2, payload: 42 },
{ type: 3, payload: 42 },
...
]; The unannotated example is the happy path where none of the expensive operations occur: There's no contextual type for the object literals, so no expensive contextual type discrimination; all elements end up having the same type, The good news with all of this is there are numerous places we could optimize:
I'll start working these ideas. |
Bug Report
π Search Terms
union array initialization performance
π Version & Regression Information
β― 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:
π Actual behavior
Checking with
--skipLibCheck --strict --extendedDiagnostics
, we see some undesirable perf variances here.The "
const
" version checks in 0.6s:The "basic array" version checks in 1.0s:
The "poisoned array" version (which is closest to the customer repro) checks in 1.3s:
The "array with extra target" version checks in 1.6s:
The "unannotated array" version checks in 0.07s (obviously not a target, but shows that these perf numbers aren't cause by "other work):
π Expected behavior
All of the array cases should be checked approximately as fast as the const version, not >2x slower.
Other notes:
The text was updated successfully, but these errors were encountered: