docs(sidebar): record how long a rebuild takes #27

Merged
dusan merged 2 commits from t3code/plan-issue-17 into main 2026-08-20 05:28:37 +00:00
Owner

Resolves the measuring half of #17.

rebuild_sidebar had never been timed. It has now been, on a release build, with a generated tree.

sessions folders rebuild (median)
5 3 1.9 ms
10 3 3.5 ms
20 3 5.3 ms
30 3 7.3 ms
50 20 13.2 ms
200 20 46.6 ms
500 20 152.6 ms
500 0 83.3 ms
500 20, cairo 138.7 ms

The design holds at the sizes it was chosen for and stops holding at about sixty sessions, where one rebuild no longer fits in a 60 Hz frame.

Widget construction is the whole cost. Of the 152.6 ms at five hundred sessions, Store::layout and the per-row settings reads are 1.7 ms — 1%. Sections are expensive too: the same five hundred sessions in one section instead of twenty cost 83 ms rather than 153 ms. The renderer barely matters, which is what you would expect if the time goes on building widgets rather than drawing them.

The periodic path is what makes it visible. With five hundred sessions and twenty of them running something whose foreground program keeps changing, the sidebar rebuilds ~6.8 times a second at ~149 ms each — about one second of main-thread work for every second there is, so the window stops drawing. The same test at fifty sessions with ten busy is 4.8 rebuilds a second at 8.1 ms, ~4% of the main thread, and fine.

What is in here

  • crates/terminalko-config/examples/gen-tree.rs — generates the tree. It erases the existing one, so it refuses to run unless GSETTINGS_BACKEND is keyfile or memory.
  • docs/spec/session-sidebar.md — the numbers, in the "Edge cases" section.

The timing instrumentation itself is not in this branch: three Instants behind a TK_TIME_SIDEBAR env var, kept local, since the numbers are the deliverable and not the scaffolding.

Not in here

No optimisation. #17 asked for a measurement first, and the measurement says the fix is #1's GtkListView over a GListStore — which builds widgets only for visible rows and can update them in place — not a second mechanism built here. #17 stays open until #1 lands.

Method, for anyone reproducing it

Release build, GSETTINGS_BACKEND=keyfile in a throwaway XDG_CONFIG_HOME, a private D-Bus session, GL renderer unless stated. Rebuilds driven by alternating session-colour over D-Bus so the tree size stays constant; median of ~30 samples, warm-up discarded. The busy sessions run bash -i -c 'while :; do sleep 0.4; timeout 0.4 sleep 9; done' — an interactive shell because without job control the children never leave the shell's process group and tcgetpgrp keeps naming the shell, so the foreground program never appears to change.

./build-aux/ci.sh and ./build-aux/smoke.sh both pass.

Resolves the measuring half of #17. `rebuild_sidebar` had never been timed. It has now been, on a release build, with a generated tree. | sessions | folders | rebuild (median) | |---|---|---| | 5 | 3 | 1.9 ms | | 10 | 3 | 3.5 ms | | 20 | 3 | 5.3 ms | | 30 | 3 | 7.3 ms | | 50 | 20 | 13.2 ms | | 200 | 20 | 46.6 ms | | 500 | 20 | **152.6 ms** | | 500 | 0 | 83.3 ms | | 500 | 20, cairo | 138.7 ms | The design holds at the sizes it was chosen for and stops holding at about sixty sessions, where one rebuild no longer fits in a 60 Hz frame. **Widget construction is the whole cost.** Of the 152.6 ms at five hundred sessions, `Store::layout` and the per-row settings reads are 1.7 ms — 1%. Sections are expensive too: the same five hundred sessions in one section instead of twenty cost 83 ms rather than 153 ms. The renderer barely matters, which is what you would expect if the time goes on building widgets rather than drawing them. **The periodic path is what makes it visible.** With five hundred sessions and twenty of them running something whose foreground program keeps changing, the sidebar rebuilds ~6.8 times a second at ~149 ms each — about one second of main-thread work for every second there is, so the window stops drawing. The same test at fifty sessions with ten busy is 4.8 rebuilds a second at 8.1 ms, ~4% of the main thread, and fine. ## What is in here - `crates/terminalko-config/examples/gen-tree.rs` — generates the tree. It erases the existing one, so it refuses to run unless `GSETTINGS_BACKEND` is `keyfile` or `memory`. - `docs/spec/session-sidebar.md` — the numbers, in the "Edge cases" section. The timing instrumentation itself is **not** in this branch: three `Instant`s behind a `TK_TIME_SIDEBAR` env var, kept local, since the numbers are the deliverable and not the scaffolding. ## Not in here No optimisation. #17 asked for a measurement first, and the measurement says the fix is #1's `GtkListView` over a `GListStore` — which builds widgets only for visible rows and can update them in place — not a second mechanism built here. #17 stays open until #1 lands. ## Method, for anyone reproducing it Release build, `GSETTINGS_BACKEND=keyfile` in a throwaway `XDG_CONFIG_HOME`, a private D-Bus session, GL renderer unless stated. Rebuilds driven by alternating `session-colour` over D-Bus so the tree size stays constant; median of ~30 samples, warm-up discarded. The busy sessions run `bash -i -c 'while :; do sleep 0.4; timeout 0.4 sleep 9; done'` — an interactive shell because without job control the children never leave the shell's process group and `tcgetpgrp` keeps naming the shell, so the foreground program never appears to change. `./build-aux/ci.sh` and `./build-aux/smoke.sh` both pass.
Measuring the sidebar needs a tree nobody would build by hand. The
example erases the existing one, so it refuses to run unless the
settings backend is keyfile or memory.
docs(sidebar): record how long a rebuild takes
Some checks failed
CI / check (push) Has been cancelled
CI / package (push) Has been cancelled
CI / check (pull_request) Has been cancelled
CI / package (pull_request) Has been cancelled
02688309fc
3.5 ms at ten sessions, 13 ms at fifty, 153 ms at five hundred
across twenty folders: past about sixty sessions one rebuild no
longer fits in a frame. Building the widgets is 99% of it, so the
fix is issue #1's list view rather than caching the model.
dusan merged commit 36568241f9 into main 2026-08-20 05:28:37 +00:00
dusan deleted branch t3code/plan-issue-17 2026-08-20 05:28:37 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dusan/terminalko!27
No description provided.