Skip to content

Commit

Permalink
test: add benchmarks for various scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
samrith-s committed Nov 12, 2024
1 parent 98759c5 commit 15ee80a
Show file tree
Hide file tree
Showing 12 changed files with 817 additions and 141 deletions.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"lint:docs": "eslint docs/**/*.ts --cache",
"prettify": "prettier --write {src,tests,docs}/**/*",
"docs": "yarn --cwd docs",
"release": "ts-node scripts/release"
"release": "vite-node scripts/release",
"bench": "vite-node src/bench/benchmarks.ts"
},
"devDependencies": {
"@commitlint/cli": "^18.4.3",
Expand Down Expand Up @@ -67,8 +68,9 @@
"rollup-plugin-typescript2": "^0.36.0",
"size-limit": "^11.0.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"vite-node": "^2.1.4",
"yocto-spinner": "^0.1.1"
},
"lint-staged": {
"*.{ts,tsx,json}": "eslint --cache --fix"
Expand Down
22 changes: 22 additions & 0 deletions src/bench/bench.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable no-var */
export {};

declare global {
declare var benchConfig: {
taskCount?: number;
timeout?: number;
};

declare type BenchmarkResult = {
Duration: string;
ELU: string;
};

declare type BenchmarkResults = Record<string, BenchmarkResult>;

declare var results = {} as {
add: (name: string, result: BenchmarkResult) => void;
delete(name: string): void;
print(): void;
};
}
18 changes: 18 additions & 0 deletions src/bench/benchmark-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const actualResults: BenchmarkResults = {};

global.benchConfig = {
taskCount: 100,
timeout: 5,
};

global.results = {
add(name, result) {
actualResults[name] = result;
},
delete(name) {
delete actualResults[name];
},
print() {
console.table(actualResults);
},
};
47 changes: 47 additions & 0 deletions src/bench/benchmarks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"use strict";

import "./benchmark-setup";

import yoctoSpinner from "yocto-spinner";

import {
with_ct_10,
with_ct_100,
with_ct_1000,
with_ct_default,
} from "./units/ct";
import { for_each } from "./units/for-each";
import { for_loop } from "./units/for-loop";
import { while_loop } from "./units/while-loop";

benchConfig.taskCount = 1000;

async function main() {
const fns = [
while_loop,
for_loop,
for_each,
with_ct_default,
with_ct_10,
with_ct_100,
with_ct_1000,
];

const spinner = yoctoSpinner({
text: "Benchmarking",
}).start();

for (const index in fns) {
const idx = Number(index);
const fn = fns[idx];
spinner.text = `Benchmarking (${idx + 1}/${fns.length}) - ${
fn.displayName
} `;
await fn();
}

spinner.success("Success!");
results.print();
}

main();
67 changes: 67 additions & 0 deletions src/bench/helpers/benchmarker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { CT } from "../..";
import { generateTasks } from "../../../testing-utils/utils/generate-tasks";

function whatIsLast(last: number) {
return function isLast(value: number, callback: () => void) {
if (value === last) {
callback();
}
};
}

type IsLast = ReturnType<typeof whatIsLast>;

export type BenchmarkArgs = {
tasks: CT.TasksWithDone;
total: number;
isLast: IsLast;
done: () => void;
};

function benchInner(
name: string,
benchmark: (args: BenchmarkArgs) => Promise<void> | void
) {
const startMark = `${name}-start`;
const endMark = `${name}-end`;

const task = performance.timerify(() => {
return new Promise((resolve) => {
const tasks = generateTasks(benchConfig.taskCount, benchConfig.timeout);
const total = tasks.length;
const isLast = whatIsLast(total - 1);

performance.mark(startMark);

benchmark({
tasks,
total,
done: () => {
resolve(true);
performance.mark(endMark);
const entry = performance.measure(name, startMark, endMark);

results.add(name, {
Duration: `${entry.duration.toFixed(2)}ms`,
ELU: `${(
performance.eventLoopUtilization().utilization * 100
).toFixed(2)}%`,
});
},
isLast,
});
});
});

const value = task as typeof task & {
displayName: string;
};

value.displayName = name;

return value;
}

export const bench = benchInner as typeof benchInner & {
displayName: string;
};
9 changes: 9 additions & 0 deletions src/bench/helpers/is-last.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function whatIsLast(last: number) {
return function isLast(value: number, callback: () => void) {
if (value === last) {
callback();
}
};
}

export type IsLast = ReturnType<typeof whatIsLast>;
19 changes: 19 additions & 0 deletions src/bench/units/ct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { TaskRunner } from "../../TaskRunner";
import { bench } from "../helpers/benchmarker";

const withCT = (name: string, concurrency = 3) =>
bench(`with-ct-${name}`, ({ done, tasks }) => {
const runner = new TaskRunner({
concurrency,
onEnd: done,
});

runner.addMultiple(tasks);

runner.start();
});

export const with_ct_default = withCT("default");
export const with_ct_10 = withCT("10", 10);
export const with_ct_100 = withCT("100", 100);
export const with_ct_1000 = withCT("1000", 1000);
9 changes: 9 additions & 0 deletions src/bench/units/for-each.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bench } from "../helpers/benchmarker";

export const for_each = bench("for-each", ({ tasks, isLast, done }) => {
tasks.forEach((task, index) => {
task(() => {
isLast(index, done);
}, index);
});
});
12 changes: 12 additions & 0 deletions src/bench/units/for-loop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { bench } from "../helpers/benchmarker";

export const for_loop = bench("for-loop", ({ tasks, isLast, done }) => {
for (const idx in tasks) {
const task = tasks[idx];
const count = Number(idx);

task(() => {
isLast(count, done);
}, count);
}
});
20 changes: 20 additions & 0 deletions src/bench/units/while-loop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { bench } from "../helpers/benchmarker";

export const while_loop = bench("while-loop", ({ tasks, isLast, done }) => {
const slicedTasks = tasks.slice();

let resolved = false;
let count = 0;

while (!resolved && slicedTasks.length) {
const task = slicedTasks.shift()!;

task(() => {
count++;
isLast(count, () => {
resolved = true;
done();
});
}, slicedTasks.length);
}
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"commitlint.config.js",
"testing-utils/**/*.ts"
],
"files": ["src/bench/bench.d.ts"],
"compilerOptions": {
"baseUrl": ".",
"module": "CommonJS",
Expand Down
Loading

0 comments on commit 15ee80a

Please sign in to comment.