-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbenchmark.js
80 lines (69 loc) · 1.91 KB
/
benchmark.js
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
const { performance } = require('perf_hooks');
const alphanumerize = require('./index.js');
// TODO make a writeup about the average and variance calculations?
// - prob need to do an inductive proof
// TODO the first time measurement skews the result, maybe throw it away?
// how do other people handle the first measurement skew? is it significant?
class Timer {
constructor() {
this.value = null;
}
start() {
this.value = performance.now();
}
end() {
this.value = performance.now() - this.value;
}
reset() {
this.value = null;
}
}
class Stats {
constructor() {
this.count = 0;
this.average = null;
this.sum_of_squares = 0;
this.square_of_sums = 0;
}
add(sample) {
this.count += 1;
this.average = this.average * ((this.count - 1) / this.count) + sample / this.count;
this.sum_of_squares = (this.sum_of_squares * (this.count - 1) + sample ** 2) / this.count;
this.square_of_sums = (
Math.sqrt(this.square_of_sums) * ((this.count - 1) / (this.count + 1))
+ Math.sqrt((sample ** 2) / (this.count * (this.count + 1)))
) ** 2;
this.variance = this.sum_of_squares - this.square_of_sums;
this.sigma = Math.sqrt(this.variance);
this.std_dev = this.sigma;
}
}
function benchmark({ name, iterations = 100, fn }) {
const timer = new Timer();
const stats = new Stats();
fn(timer);
const cold_start = timer.value;
timer.reset();
for (let i = 0; i < iterations; i += 1) {
fn(timer);
stats.add(timer.value);
timer.reset();
}
const { average, std_dev } = stats;
const speedup = cold_start / average;
// eslint-disable-next-line no-console
console.log(
'%o...bench %o ms ±%o (%o times faster than cold start)',
name, average, std_dev, speedup
);
return [average, std_dev, speedup];
}
benchmark({
name: 'timer',
iterations: 5,
fn: (timer) => {
timer.start();
alphanumerize(2);
timer.end();
}
});