From d20f3d71e3b5995e9cb153e453c8ce85fd5d54da Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 01:50:07 +0000 Subject: [PATCH] feat(cli): time the offline store-load separately from graph build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The graph_build_ms timer covered only builder.build() (the in-memory int-CSR pack, a few hundred ms). It excluded the real pre-scoring cost: reading and deserializing every kind:3 contact list out of the store. Add store_load_ms (offline path) so the three phases — store load, CSR build, scoring — are each measured and reported (stderr + JSON), instead of the load hiding behind a misleadingly small build number. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RWk2ZMrGBSr4WenKgwqmbB --- .../amethyst/cli/commands/GrapeRankCommand.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt index 30ba9fc090..f9775cf3c1 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt @@ -173,6 +173,11 @@ object GrapeRankCommand { var rounds = 0 var relaysContactedCount = 0 var contactListsFed = 0 + // Wall time to read + deserialize the contact lists out of the store + // (offline path only; online streams them in during the crawl). This + // is the real pre-scoring cost — the int-CSR build afterwards is a + // cheap in-memory pack. + var storeLoadMs: Long? = null val hopOf = HashMap() if (!offline) { @@ -365,13 +370,15 @@ object GrapeRankCommand { ) } else { // Offline: stream contact lists from the local store into the graph. + val loadStart = System.nanoTime() for (event in ctx.store.query(Filter(kinds = listOf(ContactListEvent.KIND)))) { if (event is ContactListEvent) { builder.addFollows(event.pubKey, event.verifiedFollowKeySet()) contactListsFed++ } } - System.err.println("[graperank] offline: $contactListsFed contact lists from local store") + storeLoadMs = (System.nanoTime() - loadStart) / 1_000_000 + System.err.println("[graperank] offline: $contactListsFed contact lists from local store in $storeLoadMs ms") } // Mutes + reports come from the store (both paths). Far fewer than contact @@ -426,6 +433,7 @@ object GrapeRankCommand { "graph_users" to graph.nodeCount, "graph_edges" to graph.edgeCount(), "users_scored" to rankedIds.size, + "store_load_ms" to storeLoadMs, "graph_build_ms" to buildMs, "scoring_ms" to scoringMs, "scores" to