Skip to content

Instantly share code, notes, and snippets.

@KuSh
Last active May 28, 2026 23:19
Show Gist options
  • Select an option

  • Save KuSh/7af1829312429dd6e638a47de430a86a to your computer and use it in GitHub Desktop.

Select an option

Save KuSh/7af1829312429dd6e638a47de430a86a to your computer and use it in GitHub Desktop.
// Microbenchmark: Comment `loc` access patterns with reset cycles
// Simulates oxlint lifecycle: pool init → for each file { reset → access loc ×10 → reset }
import { performance } from "node:perf_hooks";
// ── helpers ──────────────────────────────────────────────────────────────────
function computeLoc(start, end) {
return {
start: { line: start, column: 0 },
end: { line: end, column: 0 },
};
}
const N = 5000; // pool size
const N_FILES = 100; // file cycles simulated
const INNER = 10; // inner repetitions per file
// ── Variant C: prototype getter (original before PR) ─────────────────────────
class CommentC {
#loc = null;
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
get loc() {
let loc = this.#loc;
if (loc !== null) return loc;
return (this.#loc = computeLoc(this.start, this.end));
}
resetLoc() {
this.#loc = null;
}
toJSON() {
return { ...this, loc: this.loc };
}
}
Object.defineProperty(CommentC.prototype, "loc", { enumerable: true });
// ── Variant A: Proxy + WeakMap (current PR) ──────────────────────────────────
const commentsLoc = new WeakMap();
class CommentA {
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
constructor() {
return new Proxy(this, {
ownKeys(obj) {
return [...Reflect.ownKeys(obj), "loc"];
},
getOwnPropertyDescriptor(obj, prop) {
if (prop === "loc") {
return {
configurable: true,
enumerable: true,
get: () => obj.loc,
};
}
return Reflect.getOwnPropertyDescriptor(obj, prop);
},
});
}
get loc() {
let loc = commentsLoc.get(this);
if (loc !== undefined) return loc;
commentsLoc.set(this, (loc = computeLoc(this.start, this.end)));
return loc;
}
resetLoc() {
commentsLoc.delete(this);
}
}
// ── Variant B: own descriptor (module-level variable) ────────────────────────
let LOC_DESC_B;
class CommentB {
#loc = null;
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
constructor() {
Object.defineProperty(this, "loc", LOC_DESC_B);
}
resetLoc() {
this.#loc = null;
}
static {
LOC_DESC_B = {
get() {
const loc = this.#loc;
if (loc !== null) return loc;
return (this.#loc = computeLoc(this.start, this.end));
},
enumerable: true,
configurable: true,
};
}
}
// ── Variant E: own descriptor (static #desc) ─────────────────────────────────
class CommentE {
#loc = null;
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
static #LOC_DESC = {
get() {
const loc = this.#loc;
if (loc !== null) return loc;
return (this.#loc = computeLoc(this.start, this.end));
},
enumerable: true,
configurable: true,
};
constructor() {
Object.defineProperty(this, "loc", CommentE.#LOC_DESC);
}
resetLoc() {
this.#loc = null;
}
}
// ── Variant SR: self-replace accessor ────────────────────────────────────────
class CommentSR {
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
static #LOC_DESC = {
get() {
const loc = computeLoc(this.start, this.end);
Object.defineProperty(this, "loc", {
value: loc,
writable: true,
enumerable: true,
configurable: true,
});
return loc;
},
enumerable: true,
configurable: true,
};
constructor() {
Object.defineProperty(this, "loc", CommentSR.#LOC_DESC);
}
resetLoc() {
Object.defineProperty(this, "loc", CommentSR.#LOC_DESC);
}
}
// ── Variant D: #innerLoc delegation ──────────────────────────────────────────
class CommentD {
#loc = null;
start = 0;
end = 0;
range = [0, 0];
type = "Line";
value = "";
get #innerLoc() {
const loc = this.#loc;
if (loc !== null) return loc;
return (this.#loc = computeLoc(this.start, this.end));
}
static #LOC_DESC = {
get() {
return this.#innerLoc;
},
enumerable: true,
configurable: true,
};
constructor() {
Object.defineProperty(this, "loc", CommentD.#LOC_DESC);
}
resetLoc() {
this.#loc = null;
}
}
// ── pool builder ─────────────────────────────────────────────────────────────
function makePool(Cls) {
const pool = [];
for (let i = 0; i < N; i++) {
const c = new Cls();
c.start = i * 10;
c.end = i * 10 + 5;
c.range = [c.start, c.end];
c.type = (i & 1) ? "Block" : "Line";
c.value = `comment ${i}`;
pool.push(c);
}
return pool;
}
// ── tests ────────────────────────────────────────────────────────────────────
function testDirectAccess(pool) {
let count = 0;
for (let iter = 0; iter < INNER; iter++) {
for (let j = 0; j < pool.length; j++) {
const comment = pool[j];
const loc = comment.loc;
count += loc.start.line;
count += loc.start.column;
count += loc.end.line;
count += loc.end.column;
count += comment.value.length;
count += comment.type.length;
count += comment.range[0];
count += comment.range[1];
}
}
if (count === 0) throw new Error("DCE");
}
function testSpreadAccess(pool) {
let count = 0;
for (let iter = 0; iter < INNER; iter++) {
for (let j = 0; j < pool.length; j++) {
const comment = pool[j];
const copy = { ...comment };
count += copy.value.length;
}
}
if (count === 0) throw new Error("DCE");
}
// ── benchmark runner (steady state, no reset) ─────────────────────────────────
function benchNoReset(name, pool, accessFn) {
// warmup
for (let i = 0; i < 3; i++) accessFn(pool);
// measure (same N_FILES iterations for consistency)
const start = performance.now();
for (let f = 0; f < N_FILES; f++) accessFn(pool);
const elapsed = performance.now() - start;
console.log(` ${name.padEnd(10)} ${(elapsed / N_FILES).toFixed(3)} ms/file`);
}
// ── benchmark runner with reset cycles ───────────────────────────────────────
function benchWithReset(name, pool, accessFn) {
// warmup: 3 file cycles
for (let f = 0; f < 3; f++) {
for (let j = 0; j < pool.length; j++) pool[j].resetLoc();
accessFn(pool);
}
// measure: N_FILES file cycles
const start = performance.now();
for (let f = 0; f < N_FILES; f++) {
for (let j = 0; j < pool.length; j++) pool[j].resetLoc();
accessFn(pool);
}
const elapsed = performance.now() - start;
console.log(` ${name.padEnd(10)} ${(elapsed / N_FILES).toFixed(3)} ms/file`);
}
// ── main ─────────────────────────────────────────────────────────────────────
const VARIANTS = [
["C:proto", CommentC],
["A:proxy", CommentA],
["B:modvar", CommentB],
["E:static#", CommentE],
["SR:selfRp", CommentSR],
["D:delloc", CommentD],
];
console.log(`Pool: ${N}, files: ${N_FILES}, inner: ${INNER}`);
console.log("");
console.log("── No reset: direct access (steady state) ──");
for (const [name, Cls] of VARIANTS) {
const pool = makePool(Cls);
benchNoReset(name, pool, testDirectAccess);
}
console.log("");
console.log("── No reset: spread + access value.length (steady state) ──");
for (const [name, Cls] of VARIANTS) {
const pool = makePool(Cls);
benchNoReset(name, pool, testSpreadAccess);
}
console.log("");
console.log("── With reset: direct access (loc + value ×10 per file) ──");
for (const [name, Cls] of VARIANTS) {
const pool = makePool(Cls);
benchWithReset(name, pool, testDirectAccess);
}
console.log("");
console.log("── With reset: spread + access value.length (×10 per file) ──");
for (const [name, Cls] of VARIANTS) {
const pool = makePool(Cls);
benchWithReset(name, pool, testSpreadAccess);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment