From c083b40500b0496e1e8e1a32fc31b70b5e9b960d Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 24 Oct 2026 10:09:11 +0200 Subject: perf: the five heaviest processes in the CPU card, by CPU or RAM A table under RAM lists the top five processes with their CPU and resident memory, sorted by either through a toggle in the card. The toggle re-sorts the frame already held and is not saved. The rows come from one `top -b -d2` that runs only while the page is open and dies with it, checked with pgrep. ps was not used: its %CPU is a lifetime average. top's first frame is the same lifetime figure, so it is skipped. top marks no frame end but writes each frame in one burst, so a frame is published once its output has been quiet for 150ms, and rows appear about 2s after opening, not 4s as when waiting for the next header. SplitParser delivered every header after the first as "\ntop - ...", so the header match is a regex that allows leading whitespace; AGENTS.md records it. The parser is Perf.js procs(), covered in test_perf.js. Columns are right-aligned at fixed widths with tabular figures. Co-Authored-By: Claude Opus 5.5 --- desktop/modules/perf/test_perf.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'desktop/modules/perf/test_perf.js') diff --git a/desktop/modules/perf/test_perf.js b/desktop/modules/perf/test_perf.js index ac5859d..f2caa94 100644 --- a/desktop/modules/perf/test_perf.js +++ b/desktop/modules/perf/test_perf.js @@ -20,7 +20,7 @@ const src = fs.readFileSync(__dirname + "/Perf.js", "utf8") .replace(/^\.pragma library$/m, ""); const P = new Function(src + "\nreturn { cpuTimes, load, meminfo, df, vram, rate, " + "hwmonMap, lanAddr, cpuModel, du, band, worst, isIPv4, parsePubip, formatPubip, " + - "ipCheck, due, push, bytes, speed };")(); + "ipCheck, due, push, bytes, speed, procs };")(); // cpuTimes: aggregate first, then cores; idle is idle + iowait. const stat = [ @@ -156,4 +156,19 @@ assert.strictEqual(cache.total, 20); assert.deepStrictEqual(cache.items, [{ name: "a b", bytes: 9 }, { name: "b", bytes: 5 }]); assert.strictEqual(P.du(""), null); +// procs: rows after the header only, RES suffixes scaled, spaced names kept. +const frame = [ + "top - 09:50:01 up 34 min, 1 user, load average: 1.02, 0.80, 0.60", + "Tasks: 412 total, 1 running", + "", + " PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND", + " 8733 you 20 0 3824328 1.0g 140312 S 26.9 3.2 2:23.27 Isolated Web Co", + " 3772 you 20 0 1311072 191708 126420 S 5.0 0.6 2:07.86 Hyprland", +].join("\n"); +assert.deepStrictEqual(P.procs(frame), [ + { pid: 8733, name: "Isolated Web Co", cpu: 26.9, mem: 1024 ** 3 }, + { pid: 3772, name: "Hyprland", cpu: 5, mem: 191708 * 1024 }, +]); +assert.deepStrictEqual(P.procs(""), []); + console.log("test_perf: ok"); -- cgit v1.2.3