mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 08:27:04 +00:00
Phases 2.1/2.2/2.3, 3.1/3.2, 4, 5.2, and 6 of the launch-optimization plan
land together because they share a single set of seams and a single
benchmark report.
* InProcessWebsocketBuilder + LaunchFixtureRelay wrap quartz's existing
InProcessWebSocket + NostrServer (with EmptyPolicy) so any test can
drive a NostrClient against an in-memory relay seeded with arbitrary
events. Roundtrip verified by LaunchFixtureRelayTest.
* LaunchFixture builds a deterministic 50-note synthetic home-feed
snapshot from a fixed RNG seed (kind:1 + author kind:0 + kind:3 +
kind:10002). A real-world JSONL artifact is a drop-in replacement.
* NoteCard gets a stable testTag + a CompositionLocal-backed
onPlaced hook. Production overhead is one composition-local read
plus one null check per placement (default
LocalNoteCardInstrumentation = null).
* LaunchMarkers records named markers against TimeSource.Monotonic.
LaunchScenario.coldBoot drives the AccountManager (ViewOnly path)
+ DesktopLocalCache + RelayConnectionManager + LocalRelayStore
stack against the fixture relay and reports t_account_logged_in,
t_first_event, t_n_events.
* LaunchBenchmark runs 2 warmup + 5 measured iterations, computes
min/q1/median/q3/max, atomically writes the report file, and is
skipped by default — opt in via AMETHYST_BENCH=true. Baseline +
post-fix snapshots committed under desktopApp/benchmarks/.
* SubscribeBeforeConnectTest proves NostrClient / RelayPool queue REQs
issued before connect() and flush them when the connection comes up.
The bootstrap-config subscription in Main.kt drops its
`connectedRelays.first { isNotEmpty() }` + 30s withTimeoutOrNull gate
on the strength of that invariant — the subscription now fires
eagerly and recovers when no relay ever connects instead of silently
giving up after 30s.
All 274 desktopApp tests pass. No flaky tests introduced.
50 lines
1.8 KiB
Markdown
50 lines
1.8 KiB
Markdown
# Launch Benchmark
|
|
|
|
Single-JVM warm benchmark for the cold-boot critical path. See
|
|
[`desktopApp/plans/2026-06-17-feat-app-launch-optimization-plan.md`](../plans/2026-06-17-feat-app-launch-optimization-plan.md)
|
|
for the design.
|
|
|
|
## Run
|
|
|
|
```bash
|
|
AMETHYST_BENCH=true ./gradlew :desktopApp:test \
|
|
--tests "*LaunchBenchmark.run" --rerun-tasks
|
|
```
|
|
|
|
Without the env var the test class skips itself silently so a normal
|
|
`./gradlew :desktopApp:test` stays fast.
|
|
|
|
## Output
|
|
|
|
A per-git-sha report lands at
|
|
`desktopApp/build/benchmarks/launch-<git-sha>.txt`. The benchmark prints the
|
|
report to stdout and atomically writes the file via
|
|
`Files.move(... ATOMIC_MOVE)` so a killed run does not pollute the trend
|
|
data with partial content.
|
|
|
|
## Reading the numbers
|
|
|
|
Each row reports `n`, min, q1, median, q3, max in milliseconds. The
|
|
benchmark drives the slim "non-Compose" cold-boot scenario:
|
|
`AccountManager.loadSavedAccount` → relay subscription via
|
|
`InProcessWebsocketBuilder` (fixture relay) → `DesktopLocalCache.consume`.
|
|
|
|
- `t_account_logged_in` — `AccountManager.accountState` reaches
|
|
`LoggedIn(isReadOnly=true)`.
|
|
- `t_first_event` — first `kind:1` flows through `DesktopLocalCache.consume`.
|
|
- `t_n_events` — `n`th (default `n=10`) `kind:1` flows through the cache.
|
|
|
|
Numbers are dominated by the harness floor (`InProcessWebSocket` channel
|
|
hops, fixture-server REQ matching, coroutine dispatcher schedule). They
|
|
are most useful as a **regression guard** for code already in the
|
|
exercised path; they do **not** approximate a real Skia/Swing first paint.
|
|
Layered Compose-driven and JVM-fork variants are tracked as deferred
|
|
follow-ups in the plan.
|
|
|
|
## Snapshots committed here
|
|
|
|
- `baseline-main.txt` — pre-Phase-5.2 baseline.
|
|
- `with-phase5-fixes.txt` — post-Phase-5.2 snapshot.
|
|
|
|
Diff manually with `diff -u baseline-main.txt with-phase5-fixes.txt`.
|