Take the two main-thread disk reads off the startup path, and report what that bought
Both costs StrictMode found on a cold start are now off the main thread. scratchRoot is a Lazy<File>, so Context.getCacheDir - which checks and creates the private cache directory, measured at 492 ms - runs when a preview first copies something instead of while the view model is being created. The free-space probes moved into fillRootFreeSpace and fillFreeSpace, which run on Dispatchers.IO after the rows are already on screen and update the state when the filesystem answers; nothing waits for them, and fillFreeSpace checks the path is still the one on screen so a fast double-tap cannot leave a folder showing another one's number. Measured after: StrictMode no longer reports either violation, and the only ones left are MIUI's own font hook - FontSettings.loadFontSetting, TypefaceUtils.loadFontSettings, InterceptorProxy.create via MainActivity.onCreate, in 50-78 ms pairs. The debug cold start went from a 1814 ms median to 1803 ms and the benchmark coldStart from 519.5/531.6 ms to 485.6/568.9/600.0 ms. That is no improvement, and PERFORMANCE.md says so in those words: both violations were first-call costs (cache directory creation once per install, a cold StatFs page cache), the timed runs are warm, and the device's run-to-run spread of 115 ms is wider than anything the change could have bought. What it does change is the launch right after an install, which is the benchmark's first iteration: 648 ms max fresh against 550 ms warm.
This commit is contained in:
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
Generated from the source by `tools/make-code-map.py` - do not edit by hand. Regenerate it after a change (`python3 tools/make-code-map.py`); `--check` exits non-zero when this file is stale.
|
||||
|
||||
77 source files, 12741 lines - 33 test files, 386 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
77 source files, 12793 lines - 33 test files, 386 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
|
||||
Start at `AGENTS.md`. What is done, and why: `docs/ROADMAP.md` and `CHANGELOG.md`. What was verified by hand rather than by a test: `docs/EDGE_CASE_TESTING.md`.
|
||||
|
||||
@@ -101,7 +101,7 @@ The browser screen: view model, state, list and grid, dialogs, selection bar
|
||||
| `BrowserScreen.kt` | 591 | BrowserScreen() | - |
|
||||
| `BrowserTopBar.kt` | 238 | The browser's app bar: title, up, the favourite star, and the search / sort / overflow actions. BrowserTopBar(), SEARCH_FIELD_WIDTH | `BrowserTopBarTest` (4) |
|
||||
| `BrowserUiState.kt` | 311 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2100 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (89) |
|
||||
| `BrowserViewModel.kt` | 2152 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (89) |
|
||||
| `DetailsSheet.kt` | 109 | Name, location, size, type and modified date for one entry. DetailsSheet(), DetailLines(), DetailLine() | - |
|
||||
| `EntryIntents.kt` | 58 | Wraps an entry's path in a content:// URI another app may read. contentUriFor(), viewIntent(), shareIntent() | - |
|
||||
| `IncomingBar.kt` | 60 | The bar shown while another app is waiting on this one. IncomingBar() | - |
|
||||
|
||||
+29
-4
@@ -46,10 +46,35 @@ The same debug build now logs StrictMode violations, and the first cold start pr
|
||||
| 477 ms | `FileManagerTheme` → `typography = FileManagerTypography` | no — the platform loading its own typefaces on first composition |
|
||||
| 54 ms × 2 | `miui.util.font.FontSettings` via `MainActivity.onCreate` | no — the OEM's font hook doing `File.exists` while the activity is created |
|
||||
|
||||
That is **~1.5 s of main-thread disk I/O inside a 1.8 s start**, of which **~0.9 s is ours**. Both of
|
||||
ours are mechanical to move and neither is fixed yet: the cache directory is only needed when a preview
|
||||
copies something, and the free-space line on the roots screen can arrive a frame later. They are the
|
||||
first items of the speed work.
|
||||
That is **~1.5 s of main-thread disk I/O inside a 1.8 s start**, of which **~0.9 s was ours**. Both of
|
||||
ours were mechanical to move — the cache directory is only needed when a preview copies something, and the
|
||||
free-space line can arrive a frame later — and both are fixed now; what they bought, measured, is below.
|
||||
|
||||
### After the fix: what moved, and what did not
|
||||
|
||||
Both are now fixed — `scratchRoot` is a `Lazy<File>` resolved on first use, and the free-space probes run
|
||||
in `Dispatchers.IO` and update the state when they return (`fillRootFreeSpace`, `fillFreeSpace`). Measured
|
||||
afterwards:
|
||||
|
||||
| what | before | after |
|
||||
|---|---|---|
|
||||
| StrictMode at start, ours | 492 ms `cacheDir`, 397 ms `StatFs` | **gone** |
|
||||
| StrictMode at start, not ours | 477 ms typefaces, 54 ms × 2 MIUI font hook | 50–78 ms in pairs, all from `miui.util.font.FontSettings.loadFontSetting` / `TypefaceUtils.loadFontSettings` / `contentcatcher.InterceptorProxy.create` via `MainActivity.onCreate` |
|
||||
| debug cold start, 5 runs | median 1 814 ms | median 1 803 ms (1 697 · 1 752 · 1 803 · 1 823 · 2 507) |
|
||||
| `coldStart` on the benchmark build | 519.5 / 531.6 ms | 485.6 / 568.9 / 600.0 ms |
|
||||
|
||||
**The numbers did not improve, and that is worth stating rather than dressing up.** The two violations were
|
||||
*first-call* costs: creating the cache directory happens once per install, and `StatFs` is slow when its
|
||||
page cache is cold. Neither is paid on a warm device, which is what all five timed runs are — and the
|
||||
run-to-run spread on this phone (±115 ms between the three benchmark runs above) is larger than anything
|
||||
the change could have bought. What the fix does buy is that the main thread no longer does this work at
|
||||
all, which is exactly the case the benchmark's *first* iteration shows: its max is 648 ms after a fresh
|
||||
install, against 550 ms on a warm one.
|
||||
|
||||
The honest conclusion is that the remaining 1.8 s of a debug start is not made of these two calls. It is
|
||||
R8-less code, Compose's first composition, the typefaces, and MIUI's font hook — and the release-like
|
||||
build already pays 0.5 s, not 1.8 s. Making a *number* out of any further work needs either a quieter
|
||||
device or many more runs; making the *app* faster needs a baseline profile (next section).
|
||||
|
||||
## Measured on demand: the `:benchmark` module
|
||||
|
||||
|
||||
Reference in New Issue
Block a user