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

Resolver perf: Implement TreeFS.hierarchicalLookup for getClosestPackage (2/n) #1287

Closed
wants to merge 1 commit into from

Conversation

robhogan
Copy link
Contributor

Summary:
Implement a new method on TreeFS that is able to "natively" perform hierarchical lookup, such as frequently used during node_modules resolution, config path resolution, etc., and use it initially to find the closest package scope of a given candidate path (context.getClosestPackage()).

This operation currently dominates resolution time, with an algorithm that uses repeated path.dirname() and fileSystem.lookup(). The current algorithm is O(n^2) on path segments (~length), because the outer loop is O(n) and each lookup is O(n) - additionally, it's slow in constant time because each path.dirname() and path.join() involves unnecessarily parsing and normalising their own outputs - path.join() calls alone account for >30% of resolution time.

The new implementation:

  • Performs a lookup on the start path, collecting a list of all nodes along the way.
  • Looks back through each node, and checks for the existence of the subpath on each one.

Benchmarks based on collecting and running all resolutions performed during a build of rn-tester:

Before

  • Total resolution time: 1210ms
  • Time in getClosestPackage: 910ms

After

  • Total resolution time: 390ms (~3x faster)
  • Time in getClosestPackage: 105ms (~9x faster)

Differential Revision: D58062988

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 12, 2024
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D58062988

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D58062988

robhogan added a commit to robhogan/metro that referenced this pull request Aug 6, 2024
…age (2/n) (facebook#1287)

Summary:
Pull Request resolved: facebook#1287

Implement a new method on `TreeFS` that is able to "natively" perform hierarchical lookup, such as frequently used during node_modules resolution, config path resolution, etc., and use it initially to find the closest package scope of a given candidate path (`context.getClosestPackage()`).

This operation currently dominates resolution time, with an algorithm that uses repeated `path.dirname()` and `fileSystem.lookup()`. The current algorithm is O(n^2) on path segments (~length), because the outer loop is O(n) and each lookup is O(n) - additionally, it's slow in constant time because each `path.dirname()` and `path.join()` involves unnecessarily parsing and normalising their own outputs - `path.join()` calls alone account for >30% of resolution time.

The new implementation:
 - Performs a lookup on the start path, collecting a list of all nodes along the way.
 - Looks back through each node, and checks for the existence of the subpath on each one.

*Benchmarks based on collecting and running all resolutions performed during a build of rn-tester:*
## Before
 - Total resolution time: 1210ms
 - Time in `getClosestPackage`: 910ms

## After
 - Total resolution time: 390ms (~3x faster)
 - Time in `getClosestPackage`: 105ms (~9x faster)

Reviewed By: motiz88

Differential Revision: D58062988
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D58062988

robhogan added a commit to robhogan/metro that referenced this pull request Aug 12, 2024
…age (2/n) (facebook#1287)

Summary:
Pull Request resolved: facebook#1287

Implement a new method on `TreeFS` that is able to "natively" perform hierarchical lookup, such as frequently used during node_modules resolution, config path resolution, etc., and use it initially to find the closest package scope of a given candidate path (`context.getClosestPackage()`).

This operation currently dominates resolution time, with an algorithm that uses repeated `path.dirname()` and `fileSystem.lookup()`. The current algorithm is O(n^2) on path segments (~length), because the outer loop is O(n) and each lookup is O(n) - additionally, it's slow in constant time because each `path.dirname()` and `path.join()` involves unnecessarily parsing and normalising their own outputs - `path.join()` calls alone account for >30% of resolution time.

The new implementation:
 - Performs a lookup on the start path, collecting a list of all nodes along the way.
 - Looks back through each node, and checks for the existence of the subpath on each one.

*Benchmarks based on collecting and running all resolutions performed during a build of rn-tester:*
## Before
 - Total resolution time: 1210ms
 - Time in `getClosestPackage`: 910ms

## After
 - Total resolution time: 390ms (~3x faster)
 - Time in `getClosestPackage`: 105ms (~9x faster)

Reviewed By: motiz88

Differential Revision: D58062988
…age (2/n) (facebook#1287)

Summary:
Pull Request resolved: facebook#1287

Implement a new method on `TreeFS` that is able to "natively" perform hierarchical lookup, such as frequently used during node_modules resolution, config path resolution, etc., and use it initially to find the closest package scope of a given candidate path (`context.getClosestPackage()`).

This operation currently dominates resolution time, with an algorithm that uses repeated `path.dirname()` and `fileSystem.lookup()`. The current algorithm is O(n^2) on path segments (~length), because the outer loop is O(n) and each lookup is O(n) - additionally, it's slow in constant time because each `path.dirname()` and `path.join()` involves unnecessarily parsing and normalising their own outputs - `path.join()` calls alone account for >30% of resolution time.

The new implementation:
 - Performs a lookup on the start path, collecting a list of all nodes along the way.
 - Looks back through each node, and checks for the existence of the subpath on each one.

*Benchmarks based on collecting and running all resolutions performed during a build of rn-tester:*
## Before
 - Total resolution time: 1210ms
 - Time in `getClosestPackage`: 910ms

## After
 - Total resolution time: 390ms (~3x faster)
 - Time in `getClosestPackage`: 105ms (~9x faster)

Reviewed By: motiz88

Differential Revision: D58062988
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D58062988

@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 62feafa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants