Repository navigation
Conversation
`TreeFS.getSerializableSnapshot()` deep-copies the whole tree - a `Map` per directory and an array per file - before every cache write: https://github.com/react/metro/blob/1461d81e97fa8fb83a1017925c2870e260d833cc/packages/metro-file-map/src/lib/TreeFS.js#L1476-L1486 `DiskCacheManager` serialises the snapshot as soon as it asks for it, so nothing can change it in between and the copy is thrown away: https://github.com/react/metro/blob/1461d81e97fa8fb83a1017925c2870e260d833cc/packages/metro-file-map/src/cache/DiskCacheManager.js#L119-L121 This returns the tree itself. That saves a copy of the file map on every cold start, and on every save of the cache while watching. A custom cache manager (`unstable_fileMapCacheManagerFactory`) that holds on to the snapshot to serialise later would now see later changes, so `CacheManager.write`'s docs now say to serialise what `getSnapshot` returns straight away, or copy it. Expo's fork (`@expo/metro-file-map`) already skips the deep copy, for the same reason. ## Benchmark This takes 28-51% off writing the cache (Windows: 19.4ms -> 9.5ms), or 2-5% off a cold start on Linux and Windows. macOS's cold starts are too noisy to show it. The same copy was made on every save of the cache while watching, which this benchmark doesn't exercise. | | `main` | #2108 | This PR | vs `main` | vs #2108 | |---|---|---|---|---|---| | macOS: Cache write in a cold start | 7.8ms | 6.6ms | 4.3ms | -44.4% (-45.1% to -43.6%) | -34.2% (-35.4% to -33.7%) | | Linux: Cache write in a cold start | 30ms | 28ms | 20ms | -31.9% (-39.7% to -22.0%) | -27.9% (-32.0% to -25.1%) | | Windows: Cache write in a cold start | 20ms | 19.4ms | 9.5ms | -53.5% (-54.9% to -36.4%) | -51.0% (-53.2% to -32.1%) | | macOS: Cold start | 129ms | 96ms | 90ms | -30.2% (-36.0% to -22.6%) | -5.7% (-14.6% to +8.9%) | | Linux: Cold start | 648ms | 324ms | 319ms | -50.8% (-51.7% to -50.1%) | -1.8% (-5.0% to -0.5%) | | Windows: Cold start | 363ms | 179ms | 170ms | -53.2% (-53.8% to -52.5%) | -5.1% (-6.8% to -2.6%) | | macOS: Watch-mode start, cold cache | 134ms | 98ms | 96ms | -28.6% (-29.5% to -27.0%) | -2.7% (-4.5% to +0.2%) | | Linux: Watch-mode start, cold cache | 1,892ms | 470ms | 451ms | -76.1% (-76.3% to -75.8%) | -3.9% (-4.9% to -0.9%) | | Windows: Watch-mode start, cold cache | 2,556ms | 496ms | 490ms | -80.8% (-80.9% to -80.8%) | -1.1% (-1.6% to -0.7%) | ## Changelog ``` - **[Performance]**: metro-file-map: Write the cache without copying the file map first ``` ## Test plan New unit test that `DiskCacheManager` serialises the snapshot before anything else can run. Benchmark as in #2104, with 24 rounds on macOS.
This branch has not been deployed
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TreeFS.getSerializableSnapshot()deep-copies the whole tree - aMapper directory and an array per file - before every cache write:metro/packages/metro-file-map/src/lib/TreeFS.js
Lines 1476 to 1486 in 1461d81
DiskCacheManagerserialises the snapshot as soon as it asks for it, so nothing can change it in between and the copy is thrown away:metro/packages/metro-file-map/src/cache/DiskCacheManager.js
Lines 119 to 121 in 1461d81
This returns the tree itself. That saves a copy of the file map on every cold start, and on every save of the cache while watching.
A custom cache manager (
unstable_fileMapCacheManagerFactory) that holds on to the snapshot to serialise later would now see later changes, soCacheManager.write's docs now say to serialise whatgetSnapshotreturns straight away, or copy it. Expo's fork (@expo/metro-file-map) already skips the deep copy, for the same reason.Benchmark
This takes 28-51% off writing the cache (Windows: 19.4ms -> 9.5ms), or 2-5% off a cold start on Linux and Windows. macOS's cold starts are too noisy to show it. The same copy was made on every save of the cache while watching, which this benchmark doesn't exercise.
mainmainChangelog
Test plan
New unit test that
DiskCacheManagerserialises the snapshot before anything else can run. Benchmark as in #2104, with 24 rounds on macOS.