forgeTimings
uses process
How long what the web UI's pages compute takes on a codebase (tcm run tcmts.dev.forgeTimings <dir>): the warm-up
a server starts with, and the longest it holds up other work; each step the first time (cold), as the first requests
after the head moves make it; then the history summaries of the latest check entries compared with diffNamespaces of their names read whole.
import { historyList, stateAt } from "#codebase/tcmts/cli/changes"; import { openApart } from "#codebase/tcmts/cli/codebase"; import { diffNamespaces } from "#codebase/tcmts/cli/diff"; import { childrenOf, entrySummary, nameHistory, namesNow, pageOf, placeMix, projectNow, releaseHas, roleNow, shareCache, summaryOf, testsReaching, warmUp, } from "#codebase/tcmts/share"; import type { Share } from "#codebase/tcmts/share"; export async function forgeTimings( dir: string, name = "tcmts.core.hash.shortHash", check = "60", ): Promise<void> { const cb = openApart(dir); const fresh = (): Pick<Share, "cb" | "cache"> => ({ cb, cache: shareCache() }); const time = <T>(label: string, f: () => T): T => { const t = performance.now(); const v = f(); console.log(`${label.padEnd(44)} ${(performance.now() - t).toFixed(1).padStart(9)} ms`); return v; }; // the warm-up, first (from cold): how long, and the longest a page asked for meanwhile would wait const warm = fresh(); let longest = 0; let last = performance.now(); const tick = setInterval(() => { const now = performance.now(); longest = Math.max(longest, now - last); last = now; }, 1); const t = performance.now(); await warmUp(warm); clearInterval(tick); console.log( `${"warm-up".padEnd(44)} ${(performance.now() - t).toFixed(1).padStart(9)} ms, the longest wait ${longest.toFixed(1)} ms`, ); const s = fresh(); const rows = time("names (files too)", () => namesNow(s)); time("project", () => projectNow(s)); time("the map's bars (placement)", () => childrenOf(rows, projectNow(s).root).namespaces.forEach((n) => placeMix(s, n.rows, n.name)), ); time("roles of every name", () => rows.forEach((r) => roleNow(s, r))); const list = time("historyList 61", () => historyList(cb, 61)); time("history page 0 (30 summaries)", () => list.slice(0, 30).forEach((h) => entrySummary(s, h.hash)), ); time("history page 1 (30 summaries)", () => list.slice(30, 60).forEach((h) => entrySummary(s, h.hash)), ); const trees = s.cache.trees(cb); const under = name.split(".").slice(0, 2).join("."); time( `history under ${under} (400 entries)`, () => historyList(cb, 400).filter( (h) => trees .delta(cb.store.causal(h.parents[0]!)?.namespace, cb.store.causal(h.hash)!.namespace) .some((d) => d.path.startsWith(`${under}.`)) && entrySummary(s, h.hash), ).length, ); const hash = rows.find((r) => r.path === name)?.hash; if (!hash) throw new Error(`no ${name}`); time(`pageOf ${name}`, () => pageOf(s as Share, hash)); time(`testsReaching ${name}`, () => testsReaching(cb, hash).length); time(`nameHistory ${name}`, () => nameHistory(s, name)); time( "releases containing it", () => cb.store.releases().filter((r) => releaseHas(s, r.causal, hash)).length, ); // the summaries are diffNamespaces' of the entries' names read whole const checked = fresh(); let differ = 0; const n = Number(check); for (const h of historyList(cb, n)) { const d = diffNamespaces( stateAt(cb, h.parents[0]!), stateAt(cb, h.hash), (x) => cb.store.getDef(x)!.ir, ); const whole = summaryOf(d); if (JSON.stringify(whole) !== JSON.stringify(entrySummary(checked, h.hash))) { differ++; console.log(` differs: ${h.short} ${h.command}`); } } console.log( `summaries of the latest ${n} entries: ${differ ? `${differ} differ` : "all the same as diffNamespaces'"}`, ); if (differ) process.exitCode = 1; }
uses
- tcmts.cli.changes.historyList
- tcmts.cli.changes.stateAt
- tcmts.cli.codebase.openApart
- tcmts.cli.diff.diffNamespaces
- tcmts.share.Share
- tcmts.share.childrenOf
- tcmts.share.entrySummary
- tcmts.share.nameHistory
- tcmts.share.namesNow
- tcmts.share.pageOf
- tcmts.share.placeMix
- tcmts.share.projectNow
- tcmts.share.releaseHas
- tcmts.share.roleNow
- tcmts.share.shareCache
- tcmts.share.summaryOf
- tcmts.share.testsReaching
- tcmts.share.warmUp