deno.land / x / deno@v1.28.2 / tools / flamebench.js

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env -S deno run --unstable --allow-read --allow-run// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.import { join, ROOT_PATH as ROOT } from "./util.js";
async function bashOut(subcmd) { const { success, stdout } = await Deno.spawn("bash", { args: ["-c", subcmd], stdout: "piped", stderr: "null", });
// Check for failure if (!success) { throw new Error("subcmd failed"); } // Gather output const output = new TextDecoder().decode(stdout);
return output.trim();}
async function bashThrough(subcmd, opts = {}) { const { success, code } = await Deno.spawn("bash", { ...opts, args: ["-c", subcmd], stdout: "inherit", stderr: "inherit", });
// Exit process on failure if (!success) { Deno.exit(code); }}
async function availableBenches() { // TODO(AaronO): maybe reimplement with fs.walk // it's important to prune the walked tree so this is fast (<50ms) const prunedDirs = ["third_party", ".git", "target", "docs", "test_util"]; const pruneExpr = prunedDirs.map((d) => `-path ${ROOT}/${d}`).join(" -o "); return (await bashOut(` find ${ROOT} -type d \ \\( ${pruneExpr} \\) \ -prune -false -o \ -path "${ROOT}/*/benches/*" -type f -name "*.rs" \ | xargs basename | cut -f1 -d. `)).split("\n");}
function latestBenchBin(name) { return bashOut(`ls -t "${ROOT}/target/release/deps/${name}"* | head -n 1`);}
function runFlamegraph(benchBin, benchFilter, outputFile) { return bashThrough( `sudo -E flamegraph -o ${outputFile} ${benchBin} ${benchFilter ?? ""}`, // Set $PROFILING env so benches can improve their flamegraphs { env: { "PROFILING": "1" } }, );}
async function binExists(bin) { try { await bashOut(`which ${bin}`); return true; } catch (_) { return false; }}
async function main() { const { 0: benchName, 1: benchFilter } = Deno.args; // Print usage if no bench specified if (!benchName) { console.log("flamebench.js <bench_name> [bench_filter]"); // Also show available benches console.log("\nAvailable benches:"); const benches = await availableBenches(); console.log(benches.join("\n")); return Deno.exit(1); }
// List available benches, hoping we don't have any benches called "ls" :D if (benchName === "ls") { const benches = await availableBenches(); console.log(benches.join("\n")); return; }
// Ensure flamegraph is installed if (!await binExists("flamegraph")) { console.log( "flamegraph (https://github.com/flamegraph-rs/flamegraph) not found, please run:", ); console.log(); console.log("cargo install flamegraph"); return Deno.exit(1); }
// Build bench with frame pointers await bashThrough( `RUSTFLAGS='-C force-frame-pointers=y' cargo build --release --bench ${benchName}`, );
// Get the freshly built bench binary const benchBin = await latestBenchBin(benchName);
// Run flamegraph const outputFile = join(ROOT, "flamebench.svg"); await runFlamegraph(benchBin, benchFilter, outputFile);
// Open flamegraph (in your browser / SVG viewer) if (await binExists("open")) { await bashThrough(`open ${outputFile}`); }}// Runawait main();
deno

Version Info

Tagged at
a year ago