// rhysd/vim-startuptimeと同じことをしてくれるやつ const withTempFile = async (fn: (file: string) => unknown) => { const file = await Deno.makeTempFile(); try { await fn(file); } finally { await Deno.remove(file).catch(() => {}); } }; type Time = [inclusive: number, exclusive: number]; const parseLine = ( line: string, ): [key: string, time: Time] => { const [time, key] = line.split(/: /); const times = time.split(/\s+/) .map((t) => parseFloat(t)); return [key, [times[1], times[2] ?? 0]]; }; const timeToString = (time: number): string => time.toFixed(3).padStart(7, "0"); const collectResult = ( totals: number[], times: Map, exclusive: boolean, ): string => { const a = [...times.entries()] .map(([key, times]): [string, number] => [ key, times.map((t) => t[exclusive ? 1 : 0]).reduce((a, b) => a + b) / times.length, ]) .sort((a, b) => a[1] - b[1]) .map(([key, time]) => timeToString(time) + " " + key); a.push( `avg: ${ timeToString(totals.reduce((a, b) => a + b) / totals.length) } max: ${timeToString(Math.max(...totals))} min: ${ timeToString(Math.min(...totals)) }`, ); return a.join("\n"); }; withTempFile(async (file: string) => { const totals: number[] = []; const times = new Map(); // warmup await new Deno.Command(Deno.args[0], { args: [file] }).output(); for (let i = 0; i < 50; i++) { await Deno.stderr.write(new TextEncoder().encode("\r" + (i + 1))); await Deno.remove(file).catch(() => {}); await new Deno.Command(Deno.args[0], { args: [file] }).output(); const lines = (await Deno.readTextFile(file)).split(/\n/); const total = parseFloat( lines.find((line) => line.includes("VIM STARTED")) ?.replace(/\s.*/, "") ?? "", ); totals.push(total); for (const line of lines) { if (line.match(/^\d/) == null) { continue; } const [key, time] = parseLine(line); times.set(key, [time].concat(times.get(key) ?? [])); } } console.log("inclusive"); console.log(collectResult(totals, times, false)); console.log("exclusive"); console.log(collectResult(totals, times, true)); });