detached a386121

Merge pull request #52 from bnema/test/daemon-paint-benchmark-ack

test(daemon): keep paint benchmark past ack gate
commit
a386121bcb419250f311bf06e71a4425adc8f08b
author
bnema · · 2026-07-09 15:48 UTC
committer
GitHub · · 2026-07-09 15:48 UTC
merge of
ad25a70 + c31f501 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
3 files · +7 -3
M AGENTS.md +1 -1
@@ -12,7 +12,7 @@ make test
1212 go test ./internal/usecase/daemon -race -run TestName
1313 make lint
1414 make mocks
15-go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc -bench=. -benchmem
15+go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem
1616 ```
1717
1818 - Format with **goimports**.
@@ -12,7 +12,7 @@ make test
12 go test ./internal/usecase/daemon -race -run TestName12 go test ./internal/usecase/daemon -race -run TestName
13 make lint13 make lint
14 make mocks14 make mocks
15-go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc -bench=. -benchmem15+go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem
16 ```16 ```
17 17
18 - Format with **goimports**.18 - Format with **goimports**.
M docs/performance.md +3 -2
@@ -5,7 +5,7 @@ Enable daemon pprof explicitly with `VEV_PPROF_ADDR=127.0.0.1:6060 vev --daemon`
55 Run microbenchmarks with:
66
77 ```sh
8-go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc -bench=. -benchmem
8+go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem
99 ```
1010
1111 Demo flood workloads are scripted in `scripts/bench-workloads.sh` for `yes`, `seq`, and `cat` styles for raw/tmux runs. vev does not currently support `vev new <name> -- command`, so automated vev workload command overrides are intentionally not documented. Capture bytes/frame and syscalls/frame externally (for example with `strace -c` around the client/daemon) and allocations with `-benchmem`/pprof.
@@ -24,12 +24,13 @@ strace -ff -c -o tmux-cat.strace tmux new-session -d -s perf-cat 'timeout 30s sh
2424
2525 Record host CPU, OS/kernel, terminal emulator, vev commit, tmux version, terminal size, workload duration, raw command lines, syscall summaries, bytes written per rendered frame, and heap profiles or allocation counts before comparing.
2626
27-Microbenchmarks executed locally for this review using `go test ./internal/adapters/ipc -run '^$' -bench=. -benchmem`:
27+Microbenchmarks executed locally for this review using `go test ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem`:
2828
2929 | benchmark | methodology |
3030 | --- | --- |
3131 | BenchmarkTransportSend | writes encoded frames to an in-memory discard `net.Conn`; allocations reported here are Send-side frame assembly costs. |
3232 | BenchmarkTransportRecvReuse | reads a pre-encoded frame from a looping in-memory reader; no `Send` call, goroutine, channel, or frame production work runs inside the measured loop, so allocations reported here are Recv-side costs only. |
33+| BenchmarkPaintCachedSinglePaneDamage | writes a small damage update into one pane, paints through the daemon compose→diff→send path, and advances the output ACK each iteration so the measured loop does not hit the unacked-output bailout. |
3334
3435 | workload | vev baseline | tmux baseline | notes |
3536 | --- | --- | --- | --- |
@@ -5,7 +5,7 @@ Enable daemon pprof explicitly with `VEV_PPROF_ADDR=127.0.0.1:6060 vev --daemon`
5 Run microbenchmarks with:5 Run microbenchmarks with:
6 6
7 ```sh7 ```sh
8-go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc -bench=. -benchmem8+go test ./pkg/renderer ./pkg/vt ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem
9 ```9 ```
10 10
11 Demo flood workloads are scripted in `scripts/bench-workloads.sh` for `yes`, `seq`, and `cat` styles for raw/tmux runs. vev does not currently support `vev new <name> -- command`, so automated vev workload command overrides are intentionally not documented. Capture bytes/frame and syscalls/frame externally (for example with `strace -c` around the client/daemon) and allocations with `-benchmem`/pprof.11 Demo flood workloads are scripted in `scripts/bench-workloads.sh` for `yes`, `seq`, and `cat` styles for raw/tmux runs. vev does not currently support `vev new <name> -- command`, so automated vev workload command overrides are intentionally not documented. Capture bytes/frame and syscalls/frame externally (for example with `strace -c` around the client/daemon) and allocations with `-benchmem`/pprof.
@@ -24,12 +24,13 @@ strace -ff -c -o tmux-cat.strace tmux new-session -d -s perf-cat 'timeout 30s sh
24 24
25 Record host CPU, OS/kernel, terminal emulator, vev commit, tmux version, terminal size, workload duration, raw command lines, syscall summaries, bytes written per rendered frame, and heap profiles or allocation counts before comparing.25 Record host CPU, OS/kernel, terminal emulator, vev commit, tmux version, terminal size, workload duration, raw command lines, syscall summaries, bytes written per rendered frame, and heap profiles or allocation counts before comparing.
26 26
27-Microbenchmarks executed locally for this review using `go test ./internal/adapters/ipc -run '^$' -bench=. -benchmem`:27+Microbenchmarks executed locally for this review using `go test ./internal/adapters/ipc ./internal/usecase/daemon -run '^$' -bench=. -benchmem`:
28 28
29 | benchmark | methodology |29 | benchmark | methodology |
30 | --- | --- |30 | --- | --- |
31 | BenchmarkTransportSend | writes encoded frames to an in-memory discard `net.Conn`; allocations reported here are Send-side frame assembly costs. |31 | BenchmarkTransportSend | writes encoded frames to an in-memory discard `net.Conn`; allocations reported here are Send-side frame assembly costs. |
32 | BenchmarkTransportRecvReuse | reads a pre-encoded frame from a looping in-memory reader; no `Send` call, goroutine, channel, or frame production work runs inside the measured loop, so allocations reported here are Recv-side costs only. |32 | BenchmarkTransportRecvReuse | reads a pre-encoded frame from a looping in-memory reader; no `Send` call, goroutine, channel, or frame production work runs inside the measured loop, so allocations reported here are Recv-side costs only. |
33+| BenchmarkPaintCachedSinglePaneDamage | writes a small damage update into one pane, paints through the daemon compose→diff→send path, and advances the output ACK each iteration so the measured loop does not hit the unacked-output bailout. |
33 34
34 | workload | vev baseline | tmux baseline | notes |35 | workload | vev baseline | tmux baseline | notes |
35 | --- | --- | --- | --- |36 | --- | --- | --- | --- |
M internal/usecase/daemon/render_test.go +3 -0
@@ -574,6 +574,9 @@ func BenchmarkPaintCachedSinglePaneDamage(b *testing.B) {
574574 for i := 0; i < b.N; i++ {
575575 right.screen.Write([]byte("x\b"))
576576 d.paint(sess, ac, false)
577+ // Mirror the client ACK pump so the steady state measures compose→diff→send,
578+ // not the ack-gate bailout after maxUnackedOutputStates frames.
579+ ac.advanceOutputAck(ac.nextStateNum)
577580 }
578581 }
579582
@@ -574,6 +574,9 @@ func BenchmarkPaintCachedSinglePaneDamage(b *testing.B) {
574 for i := 0; i < b.N; i++ {574 for i := 0; i < b.N; i++ {
575 right.screen.Write([]byte("x\b"))575 right.screen.Write([]byte("x\b"))
576 d.paint(sess, ac, false)576 d.paint(sess, ac, false)
577+ // Mirror the client ACK pump so the steady state measures compose→diff→send,
578+ // not the ack-gate bailout after maxUnackedOutputStates frames.
579+ ac.advanceOutputAck(ac.nextStateNum)
577 }580 }
578 }581 }
579 582

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 13

↑↓ moveenter openesc close