You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
-102Lines changed: 0 additions & 102 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,105 +21,3 @@ Use `scripts/dependency-topology/scan_topology.py` to inspect and track architec
21
21
- Pass `--snapshot <git-ref>` for historical snapshots
22
22
- Pass `--json` when feeding outputs into scripts or agents
23
23
- Keep architecture cleanup discussions anchored on scanner output instead of ad-hoc grep chains
24
-
25
-
## Runtime Performance Profiling
26
-
27
-
Use this section when there is a runtime performance problem or a credible performance report: slow render, delayed keypress, streaming lag, startup slowdown, a profiler screenshot, or a benchmark/test showing a regression. Before changing code for that problem, capture evidence and reduce it to a cost model. Pick the profiling method by what is available; do not require a specific plugin.
28
-
29
-
### Capture options
30
-
31
-
Use the first option that fits the machine and the symptom.
32
-
33
-
#### Instrumentation profiler
34
-
35
-
Use this when a profiler plugin is already available. It records function call trees with time and count.
36
-
37
-
Example with `folke/snacks.nvim`, if it is installed:
38
-
39
-
```vim
40
-
:lua Snacks.profiler.start()
41
-
" reproduce the slow action once
42
-
:lua Snacks.profiler.stop({ pick = true })
43
-
```
44
-
45
-
Read it as a call tree. Parent time includes child time. `count` is useful for spotting repeated work.
46
-
47
-
#### LuaJIT sampling profiler
48
-
49
-
Use this when no profiler plugin is available. Neovim normally exposes LuaJIT's profiler as `jit.p`.
Open `/tmp/nvim-jit-profile.log`. Treat it like a sampled CPU profile: it shows where Lua spent CPU time by stack/location, but it does not give exact call counts. If the issue is repeated work, pair it with a counter or scoped timer.
58
-
59
-
#### Scoped wall-time timer
60
-
61
-
Use this when the question is “which lifecycle boundary blocks the user?” or when sampling does not show wall-clock delay. Add temporary instrumentation around suspected boundaries only while investigating.
count: <hotspot calls per trigger, or "sampled" if using jit.p>
104
-
cost: <hotspot total time and per-call time if available>
105
-
repeated unit: <message | part | line | file | buffer | session>
106
-
invariant data: <inputs that are unchanged across repeated calls>
107
-
```
108
-
109
-
Rules for reading evidence:
110
-
111
-
- In instrumentation traces, parent time includes child time. If parent and child times are almost equal, optimize the child or the child's call frequency.
112
-
- In sampling traces, sample share is not exact wall time and does not prove call count. Use it to find the hot stack, then verify count with instrumentation or counters.
113
-
- A 400 ms function called 10 times is a repeated-work problem. A 4 s function called once is a single expensive operation.
114
-
- Do not optimize tiny high-count helpers unless their caller stack explains the user-visible delay.
115
-
116
-
### Fix criteria
117
-
118
-
A valid fix must change one measured fact:
119
-
120
-
- remove expensive work from the blocking path;
121
-
- move invariant work to the smallest valid lifecycle boundary;
122
-
- defer work to an explicit user action;
123
-
- reduce repeated calls and prove the new call count with a test.
124
-
125
-
Do not add a cache until its invalidation boundary is named. Acceptable boundaries are concrete lifecycle points such as one render flush, one full session render, one keypress, one state change subscription, or one buffer change. Add a regression test that fails on the old call count.
0 commit comments