-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.ts
113 lines (97 loc) · 3.13 KB
/
helpers.ts
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
import { ExecSyncOptionsWithStringEncoding as ExecOptionsWithStringEncoding } from "child_process";
import humanizeDuration, { HumanizerOptions } from "humanize-duration";
import { mean, std } from "mathjs";
import {
coolDownBeforeAndBetweenBenchmarksSeconds,
runBenchmarksTimes,
} from "./config.js";
// from https://stackoverflow.com/a/30452949/4536543
const runAsyncFunctionTimes =
(repeatTimes: number) =>
async (asyncFunctionToRepeat: () => Promise<unknown>) => {
if (repeatTimes > 0) {
await asyncFunctionToRepeat();
await runAsyncFunctionTimes(repeatTimes - 1)(asyncFunctionToRepeat);
}
};
const secondsToMs = (seconds: number) => seconds * 1_000;
const nanosecondsToMs = (nanoseconds: number) => nanoseconds / 1_000_000;
const measureAsyncFunctionTimeInMs = async (
asyncFunctionToMeasure: () => Promise<unknown>
) => {
const startTime = process.hrtime();
await asyncFunctionToMeasure();
const elapsedTime = process.hrtime(startTime);
return secondsToMs(elapsedTime[0]) + nanosecondsToMs(elapsedTime[1]);
};
export const measureAverageAsyncFunctionTimeInMs = async (
asyncFunctionToMeasure: () => Promise<unknown>,
times = runBenchmarksTimes || 3,
onlyConsecutive = true,
coolDownSeconds = coolDownBeforeAndBetweenBenchmarksSeconds || 5
) => {
const totals: number[] = [];
if (onlyConsecutive) {
await asyncFunctionToMeasure(); // first run doesn't count (caching, etc.)
}
sleep(coolDownSeconds); // sleep before running benchmarks
await runAsyncFunctionTimes(times)(async () => {
totals.push(await measureAsyncFunctionTimeInMs(asyncFunctionToMeasure));
sleep(coolDownSeconds);
});
return totals;
};
export const analyseTotals = (
totals: number[]
): { mean: number; std: number } => ({
mean: mean(totals) as number,
std: std(totals, "unbiased"),
});
export const execDefaultOptions: ExecOptionsWithStringEncoding = {
encoding: "utf-8",
};
// const nvm = (projectRootFolder: Project["rootFolder"]) => {
// const getCommand = () => {
// if (existsSync(join(projectRootFolder, ".nvmrc"))) {
// return "nvm i";
// }
// return `nvm i ${
// JSON.parse(readFileSync(join(projectRootFolder, "package.json"), "utf-8"))
// .engines.node
// }`;
// };
// execSync(getCommand(), {
// ...execSyncDefaultOptions,
// cwd: projectRootFolder,
// shell: "/bin/bash",
// });
// };
const shortEnglishHumanizer = humanizeDuration.humanizer({
language: "shortEn",
languages: {
shortEn: {
y: () => "y",
mo: () => "mo",
w: () => "w",
d: () => "d",
h: () => "h",
m: () => "m",
s: () => "s",
ms: () => "ms",
},
},
});
export const humanizeDurationRound = (timeMs: number) => {
const options: HumanizerOptions = { round: true, spacer: "" };
if (timeMs < 10000) {
// add ms to times that are less than 10 seconds
options.units = ["y", "mo", "w", "d", "h", "m", "s", "ms"];
}
return shortEnglishHumanizer(timeMs, options);
};
/**
* @param seconds Seconds to wait
*/
export const sleep = (seconds: number) => {
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, seconds * 1000);
};