mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
tools(bench): rebootstrap (#12281)
Enable deno devs to bench/profile/test JS code changes without doing a full --release rebuild. Incremental release builds take ~4mn on M1s, often more on other machines ...
This commit is contained in:
parent
6bf5c850e6
commit
b3ceafaa5d
4 changed files with 85 additions and 0 deletions
33
tools/bench/README.md
Normal file
33
tools/bench/README.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
## Re-bootstrapping
|
||||||
|
|
||||||
|
Re-bootstrapping allows deno devs to bench/profile/test JS-side changes without
|
||||||
|
doing a full `cargo build --release --bin deno` which takes roughly ~4mn on M1s
|
||||||
|
more on other machines which significantly slows down iteration &
|
||||||
|
experimentation.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { benchSync, rebootstrap } from "./tools/bench/mod.js";
|
||||||
|
|
||||||
|
const bootstrap = rebootstrap([
|
||||||
|
"webidl",
|
||||||
|
"console",
|
||||||
|
"url",
|
||||||
|
"web",
|
||||||
|
"fetch",
|
||||||
|
]);
|
||||||
|
|
||||||
|
benchSync("resp_w_h", 1e6, () =>
|
||||||
|
new bootstrap.fetch.Response("yolo", {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
server: "deno",
|
||||||
|
"content-type": "text/plain",
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
This code can then benched and profiled (using Chrome's DevTools) similar to
|
||||||
|
regular userland code and the original source files appear in the DevTools as
|
||||||
|
you would expect.
|
2
tools/bench/mod.js
Normal file
2
tools/bench/mod.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./rebench.js";
|
||||||
|
export * from "./rebootstrap.js";
|
25
tools/bench/rebench.js
Normal file
25
tools/bench/rebench.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
export function benchSync(name, n, innerLoop) {
|
||||||
|
const t1 = Date.now();
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
innerLoop(i);
|
||||||
|
}
|
||||||
|
const t2 = Date.now();
|
||||||
|
console.log(benchStats(name, n, t1, t2));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function benchAsync(name, n, innerLoop) {
|
||||||
|
const t1 = Date.now();
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
await innerLoop(i);
|
||||||
|
}
|
||||||
|
const t2 = Date.now();
|
||||||
|
console.log(benchStats(name, n, t1, t2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function benchStats(name, n, t1, t2) {
|
||||||
|
const dt = (t2 - t1) / 1e3;
|
||||||
|
const r = n / dt;
|
||||||
|
const ns = Math.floor(dt / n * 1e9);
|
||||||
|
return `${name}:${" ".repeat(20 - name.length)}\t` +
|
||||||
|
`n = ${n}, dt = ${dt.toFixed(3)}s, r = ${r.toFixed(0)}/s, t = ${ns}ns/op`;
|
||||||
|
}
|
25
tools/bench/rebootstrap.js
Normal file
25
tools/bench/rebootstrap.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { dirname, fromFileUrl, join } from "https://deno.land/std/path/mod.ts";
|
||||||
|
import { expandGlobSync } from "https://deno.land/std/fs/mod.ts";
|
||||||
|
|
||||||
|
const ROOT_DIR = join(dirname(fromFileUrl(import.meta.url)), "..", "..");
|
||||||
|
|
||||||
|
export function rebootstrap(exts) {
|
||||||
|
[
|
||||||
|
"core/00_primordials.js",
|
||||||
|
...exts.map((e) => `ext/${e}/*.js`),
|
||||||
|
]
|
||||||
|
.map((pattern) => join(ROOT_DIR, pattern))
|
||||||
|
.map((pattern) => [...expandGlobSync(pattern)])
|
||||||
|
.flat()
|
||||||
|
.map((entry) => entry.path)
|
||||||
|
.forEach((file) => {
|
||||||
|
Deno.core.evalContext(Deno.readTextFileSync(file), file);
|
||||||
|
});
|
||||||
|
const bootstrap = globalThis.__bootstrap;
|
||||||
|
delete globalThis.__bootstrap;
|
||||||
|
// Patch dispatchEvent so we don't crash when MainWorker exits via:
|
||||||
|
// `window.dispatchEvent(new Event('unload'))`
|
||||||
|
// which fails since symbols are mangled during rebootstrap
|
||||||
|
globalThis.dispatchEvent = () => {};
|
||||||
|
return bootstrap;
|
||||||
|
}
|
Loading…
Reference in a new issue