summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/bench/README.md33
-rw-r--r--tools/bench/mod.js2
-rw-r--r--tools/bench/rebench.js25
-rw-r--r--tools/bench/rebootstrap.js25
4 files changed, 85 insertions, 0 deletions
diff --git a/tools/bench/README.md b/tools/bench/README.md
new file mode 100644
index 000000000..78529d106
--- /dev/null
+++ b/tools/bench/README.md
@@ -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.
diff --git a/tools/bench/mod.js b/tools/bench/mod.js
new file mode 100644
index 000000000..685834281
--- /dev/null
+++ b/tools/bench/mod.js
@@ -0,0 +1,2 @@
+export * from "./rebench.js";
+export * from "./rebootstrap.js";
diff --git a/tools/bench/rebench.js b/tools/bench/rebench.js
new file mode 100644
index 000000000..bbc5a3c2f
--- /dev/null
+++ b/tools/bench/rebench.js
@@ -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`;
+}
diff --git a/tools/bench/rebootstrap.js b/tools/bench/rebootstrap.js
new file mode 100644
index 000000000..b85276ef3
--- /dev/null
+++ b/tools/bench/rebootstrap.js
@@ -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;
+}