The Wayback Machine - https://web.archive.org/web/20211015100157/https://github.com/angular/angular/pull/41271
Skip to content
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

perf(compiler-cli): optimize cycle detection using a persistent cache #41271

Closed
wants to merge 1 commit into from

Conversation

@JoostK
Copy link
Member

@JoostK JoostK commented Mar 18, 2021

For the compilation of a component, the compiler verifies that the
imports it needs to generate to reference the used directives and pipes
would not create an import cycle in the program. This requires visiting
the transitive import graphs of all directive/pipe usage in search of
the component file. The observation can be made that all directive/pipe
usages can leverage the exploration work in search of the component
file, thereby allowing sub-graphs of the import graph to be only visited
once instead of repeatedly per usage. Additionally, the transitive
imports of a file are no longer collected into a set to reduce memory
pressure.

@ngbot ngbot bot added this to the Backlog milestone Mar 18, 2021
@google-cla google-cla bot added the cla: yes label Mar 18, 2021
@JoostK JoostK force-pushed the ngtsc/perf/transitive-imports branch from 1ef37ce to 3fe06cf Mar 20, 2021
@JoostK JoostK changed the title ngtsc transitive imports experiment perf(compiler-cli): optimize cycle detection using a persistent cache Mar 20, 2021
@JoostK JoostK force-pushed the ngtsc/perf/transitive-imports branch from 3fe06cf to 278e92e May 4, 2021
@JoostK JoostK marked this pull request as ready for review May 4, 2021
@JoostK JoostK force-pushed the ngtsc/perf/transitive-imports branch from 278e92e to 118b64a Jul 13, 2021
@JoostK
Copy link
Member Author

@JoostK JoostK commented Jul 13, 2021

I am seeing noticeable improvements in several different projects with this change; cycle detection timings going from ~500ms to ~200ms. Since this runs on each incremental rebuild, that is a nice win (overall resolve phase time reduces from ~800ms to ~500ms)

Copy link
Contributor

@alxhub alxhub left a comment

Super clever!

this.importGraph.addSyntheticImport(from, to);
}
}

const NgCyclicResult = Symbol('NgCyclicResult');
type CyclicResultMarker = {};
Copy link
Contributor

@alxhub alxhub Jul 13, 2021

Use a branded type to avoid open assignability.

alxhub
alxhub approved these changes Jul 13, 2021
For the compilation of a component, the compiler verifies that the
imports it needs to generate to reference the used directives and pipes
would not create an import cycle in the program. This requires visiting
the transitive import graphs of all directive/pipe usage in search of
the component file. The observation can be made that all directive/pipe
usages can leverage the exploration work in search of the component
file, thereby allowing sub-graphs of the import graph to be only visited
once instead of repeatedly per usage. Additionally, the transitive
imports of a file are no longer collected into a set to reduce memory
pressure.
@AndrewKushnir
Copy link
Contributor

@AndrewKushnir AndrewKushnir commented Jul 13, 2021

Copy link
Member

@petebacondarwin petebacondarwin left a comment

Nice.

What happens in an incremental build where a file (e.g. a.ts) that was previously part of a cycle (e.g. a.ts->b.ts->a.ts) is not changed but another file (e.g. b.ts) is changed to break the cycle. Will the a.ts SourceFile object still contain the sf[NgCyclicResult] marker?

Answering my own question, I think, it seems that a new CycleResults instance would be created that would have a new unique cyclic object property. So even though a.ts will contain an object in its sf[NgCyclicResult] property, this object would not match the new one from the new CycleResults instance. Right?

@JoostK
Copy link
Member Author

@JoostK JoostK commented Jul 14, 2021

Indeed, that's why the unique markers are used.

alxhub added a commit that referenced this issue Jul 15, 2021
…#41271)

For the compilation of a component, the compiler verifies that the
imports it needs to generate to reference the used directives and pipes
would not create an import cycle in the program. This requires visiting
the transitive import graphs of all directive/pipe usage in search of
the component file. The observation can be made that all directive/pipe
usages can leverage the exploration work in search of the component
file, thereby allowing sub-graphs of the import graph to be only visited
once instead of repeatedly per usage. Additionally, the transitive
imports of a file are no longer collected into a set to reduce memory
pressure.

PR Close #41271
@alxhub alxhub closed this in 07d7e60 Jul 15, 2021
@angular-automatic-lock-bot
Copy link

@angular-automatic-lock-bot angular-automatic-lock-bot bot commented Aug 15, 2021

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants