This repository has been archived by the owner on Feb 12, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize ReactEquivalenceSet (#2243)
Summary: I generated the following program (now added to test cases) and while I would expect its evaluation in Prepack to terminate reasonably quickly, I did not see the program terminate after five minutes of execution: https://gist.github.com/calebmer/2bf1d84a5b7849fa732bce69811df10b After this change that same program’s Prepack evaluation terminates in about two seconds. This change also saves about 2.8s on the evaluation of our internal bundle which is about 3% of the total time. What was happening? Why did my program fail to terminate execution in five minutes? Why was the internal bundle relatively ok compared to my extreme case? In my program, I would [expect the component `Mu`](https://gist.github.com/calebmer/2bf1d84a5b7849fa732bce69811df10b#file-program-js-L289-L291) to be inlined about 60 times. Which means there should only be about 60 calls to `ReactElementSet#add` for each of `Mu`’s `div`s. However, after some basic instrumentation I observed way over ten thousand visits to these React elements. This pair of method calls happens a couple times in `ReactEquivalenceSet` and friends. https://github.com/facebook/prepack/blob/5f7256f17ed1bca84ed2f8c80a72d9251a32fc43/src/react/ReactEquivalenceSet.js#L233-L234 Both `getEquivalentPropertyValue`… https://github.com/facebook/prepack/blob/5f7256f17ed1bca84ed2f8c80a72d9251a32fc43/src/react/ReactEquivalenceSet.js#L255 …and `getValue`… https://github.com/facebook/prepack/blob/5f7256f17ed1bca84ed2f8c80a72d9251a32fc43/src/react/ReactEquivalenceSet.js#L104 …end up calling `ReactElementSet#add` with the same React element. Then `ReactElementSet#add` ends up recursing into children. So the root element is added 2 times, so the root’s children are added 4 times each, so each child of those elements are added 8 times each, and so on. So if a leaf element is `n` deep in the tree it will be added `2^n` times. The most nested `Mu` child was 9 elements deep. `Mu` appeared 60 times at many levels of nesting. I’m not entirely sure why my generated case was so much worse then our internal bundle. My two best guesses are: lots of repeated components or deeper nesting? My fix was to move the `getValue` call into `getEquivalentPropertyValue`. This way if `getEquivalentPropertyValue` already finds an equivalent value we can short-circuit and not run `getValue` which will perform the same operation. Pull Request resolved: #2243 Reviewed By: trueadm Differential Revision: D8811463 Pulled By: calebmer fbshipit-source-id: 4f30a75e96c6592456f5b21ee9c2ee3e40b56d81
- Loading branch information
1 parent
1a4ab4e
commit 37d6924
Showing
7 changed files
with
5,415 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
/node_modules | ||
/lib | ||
npm-debug.log | ||
yarn-error.log | ||
.DS_Store | ||
build/ | ||
.idea/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.