From 50e91395a2b82f586b50eafb57df945f01a3058c Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 21 Sep 2026 23:16:01 -0300 Subject: Measure time to first paint, which is the startup number that matters --version measures a process that exits before doing any work. On a pty the tty shell emits its first byte at 20 ms and settles at 50 ms; the gui takes ~330 ms to map its window, and that is the latency worth noticing. Of the gui's 330 ms, ~95% is CPU and only ~30 ms is waiting. Profiled warm and killed before the map: pardes-gui 28.5%, libc 20.7%, ld-linux 11.9%, libudev 10.3%, the nvidia stack ~21%. Cutting across all of those, DWARF unwinding is 20.9% of samples -- the Debug allocator capturing six frames per allocation, the same cost the previous change found, and now the largest single slice. Two of my own measurements were wrong and are corrected here. An earlier ~510 ms figure was an artifact: the probe redirected HOME, so the nvidia shader cache was cold and the driver recompiled every launch. And deferring SDL_INIT_GAMEPAD past the first frame, on the theory that libudev's 10% was gamepad enumeration, changed the map time not at all (320-366 ms either way) and libudev only 10.3% -> 9.6%: that work belongs to SDL_INIT_VIDEO bringing up Wayland seats. It is reverted rather than kept as an unmeasurable win. So nothing in the editor's own logic is slow to start. What is left is the Debug allocator and the GPU stack, and the only lever on either is the build mode -- which is not worth tripling a ten-minute build for. Co-Authored-By: Claude Opus 5 (1M context) --- features.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/features.txt b/features.txt index 9933dd14..7515d455 100644 --- a/features.txt +++ b/features.txt @@ -112,3 +112,27 @@ Recommendation: do NOT chase this. 22 ms warm is imperceptible for an editor, th switching the default from Debug to ReleaseSafe would multiply an already ~10 minute build to save 18 ms of startup -- a bad trade when the build is the actual bottleneck in this project. Worth knowing for the day a binary ships to someone else: ReleaseSafe keeps the safety checks, drops the debug allocator, and is 5x faster to start and 10x smaller. + +Refactor Msg, and the other transient text a builtin shows (prompts for input and the like), to use the same line mechanism the treesitter context uses rather +than its own. Keep one piece of state on the pane tracking those lines, so several of them do not overlap, so they cooperate, and so removing one puts the rest +back where they belong. Keep it simple. + +Startup, the number that actually matters: time to first paint, measured on the real binaries rather than on --version. + + pardes --tty on a pty first byte 20 ms, settled 50 ms (8.3 KB in 12 bursts) -- unchanged with LSP enabled + pardes-gui to window map ~330 ms warm, of which ~95% is CPU and only ~30 ms is waiting + +The ~1 s that gets noticed is the gui, and ~330 ms of it is real (the rest is presumably paint and content after the map). +Profiled warm (perf record, killed pre-map), by shared object: pardes-gui 28.5%, libc 20.7%, ld-linux 11.9%, libudev 10.3%, +nvidia glcore+eglcore+glsi+gpucomp ~21%, xkbcommon 2%. Cutting across those, DWARF unwinding is 20.9% of all samples -- +the Debug allocator's per-allocation stack capture again, now the single largest identifiable slice, bigger than any one +driver library. An earlier measurement of ~510 ms was my own artifact: the probe redirected HOME, so ~/.cache/nvidia was +cold and the driver recompiled shaders every run. + +Tried and reverted: deferring SDL_INIT_GAMEPAD until after the first frame, on the theory that libudev's 10% was device +enumeration for a gamepad most sessions do not have. Measured: window map unchanged (320-366 ms before and after) and +libudev only moved 10.3% -> 9.6%. The udev cost belongs to SDL_INIT_VIDEO enumerating Wayland seats and input, not to the +gamepad subsystem. Two fields and a branch for nothing, so it went back out. + +Conclusion for both platforms: nothing in pardes's own logic is slow at startup. The cost is the Debug build's allocator +tracing and the GPU/driver stack coming up, and the only lever on either is the build mode. -- cgit v1.3