mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
docs: record the tick sweep that picked 30s for the dedup age-out
30s was the one number in this change I picked rather than measured. Swept it on device (10/30/60/120s). The naive comparison is invalid: runs pull 3.7k-32k frames depending on what the relays serve, so hit rate and heap at the end of a run are not comparable. Comparing at a matched ~19k frames instead: tick hit rate parses ids still cached at rest 10s 44.9% 10,663 ~2 30s 58.5% 7,569 ~2 60s 60.4% 7,520 ~3 120s 60.6% 7,555 7,438 Hit rate saturates by 30s, so a shorter tick buys only re-parses (10s costs 41% more) and a longer one only holds memory -- at 120s just one tick fires in three minutes, so the burst never drops at all. The knee is where the tick stops being the binding constraint and capacity takes over: at ~400 frames/s that is 8192/400 ~= 20s, and 30s sits just past it. Keeps 30s; documents why, and what to re-measure if capacity or frame rates change. No behaviour change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ccebc3d344
commit
b1f1190919
+18
@@ -228,6 +228,24 @@ class NostrClient(
|
||||
* Ids survive one tick and die on the next, so [DECODER_AGE_OUT_MS] bounds their
|
||||
* lifetime at ~2x that. Suspends on [isActiveFlow] like [keepAliveJob], so no timer
|
||||
* fires while the client is down — [disconnect] clears outright on the way there.
|
||||
*
|
||||
* 30s is measured, not guessed. Sweeping the interval on device and comparing hit
|
||||
* rate at a matched ~19k frames (runs pull different volumes, so raw endpoints are
|
||||
* not comparable):
|
||||
*
|
||||
* ```
|
||||
* tick hit rate parses ids still cached at rest
|
||||
* 10s 44.9% 10,663 ~2
|
||||
* 30s 58.5% 7,569 ~2
|
||||
* 60s 60.4% 7,520 ~3
|
||||
* 120s 60.6% 7,555 7,438 (one tick in 3 min -> never releases)
|
||||
* ```
|
||||
*
|
||||
* Hit rate saturates by 30s, so a shorter tick only buys re-parses (10s costs 41%
|
||||
* more), and a longer one only holds memory. The knee is where the tick stops being
|
||||
* the binding constraint and [CachingEventDecoder.capacity] takes over: at the
|
||||
* observed ~400 frames/s that crossover is 8192/400 ~= 20s, so 30s sits just past
|
||||
* it. Re-measure if capacity or typical frame rates change.
|
||||
*/
|
||||
private val decoderTrimJob =
|
||||
scope.launch {
|
||||
|
||||
Reference in New Issue
Block a user