Thanks for the report (and repro case, which I can confirm on my local workstation). The majority of this slowdown seems to be algorithmic overhead in our module fetching logic.
kou… via monorail
unread,
May 16, 2017, 5:54:39 PM5/16/17
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
Progress update: The 2 CLs below should get us into a better state. Applying both would improve local benchmark scores by 4x, and I have more optimization ideas that I plan to work on next week.
This has all the same symptoms as issue 740874, and I suspect has the same root cause: a module graph with lots of interconnections. E.g., _baseIteratee.js is imported the most (43 times); it imports five other modules, which themselves collectively import another 14 modules, which...import more stuff. So if we're creating a ModuleTreeLinker per path-to-a-module, it is indeed going to add up fast (I see a total of ~360,000 MTLs created overall).
bugdro… via monorail
unread,
Jul 20, 2017, 8:15:00 AM7/20/17
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
Before this CL, we instantiated ModuleTreeLinker per module graph edge (== import stmt). For module graphs which are close to fully connected, this resulted in exponential number of ModuleTreeLinker involved. Each ModuleTreeLinker comes w/ multiple postTask cost and memory cost, thus this resulted in slow performance and high peak memory usage.
This CL drastically reduces the ModuleTreeLinker per module graph fetch, by creating one ModuleTreeLinker at most for each module graph node (== module script) involved. This CL introduces ModuleTreeReachedUrlSet, which is instantiated per top-level module graph fetch, and shared among all descendant sub-graph ModuleTreeLinkers. Before creating a new ModuleTreeLinker for descendant module graph fetch, ModuleTreeLinker::FetchDescendants now consults this ModuleTreeReachedUrlSet to find if there is an existing ModuleTreeLinker instance which it can delegate the sub-graph fetch.
Credits: - nhiroki@ for the original algorithm. - adamk@, hiroshige@ for extensive analysis. - adamk@, ksakamoto@ for verifying the speed up.