Created
January 14, 2026 17:32
-
-
Save bvisness/9f6b3bfb10e6fd7ed248555e241368ce to your computer and use it in GitHub Desktop.
A little JS timing utility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Stopwatch { | |
| constructor(name, silent = false) { | |
| this.silent = silent; | |
| this.samples = []; | |
| this.reset(name); | |
| } | |
| reset(name) { | |
| this.name = name; | |
| this.last = performance.now(); | |
| this.samples.length = 0; | |
| } | |
| prep() { | |
| this.last = performance.now(); | |
| } | |
| click() { | |
| const now = performance.now(); | |
| const delta = now - this.last; | |
| if (!this.silent) { | |
| print(`${this.name}: ${delta.toFixed(3)}ms`); | |
| } | |
| this.samples.push(delta); | |
| this.last = now; | |
| } | |
| min() { | |
| if (this.samples.length === 0) { | |
| return 0; | |
| } | |
| let min = Infinity; | |
| for (const sample of this.samples) { | |
| if (sample < min) { | |
| min = sample; | |
| } | |
| } | |
| return min; | |
| } | |
| max() { | |
| let max = 0; | |
| for (const sample of this.samples) { | |
| if (sample > max) { | |
| max = sample; | |
| } | |
| } | |
| return max; | |
| } | |
| mean() { | |
| let sum = 0; | |
| for (const sample of this.samples) { | |
| sum += sample; | |
| } | |
| return sum / this.samples.length; | |
| } | |
| stddev() { | |
| const mean = this.mean(); | |
| const squaredDevs = this.samples.map(x => (x - mean) ** 2); | |
| let devSum = 0; | |
| for (const squaredDev of squaredDevs) { | |
| devSum += squaredDev; | |
| } | |
| const variance = devSum / this.samples.length; | |
| const stddev = Math.sqrt(variance); | |
| return stddev; | |
| } | |
| median() { | |
| const median = this.samples[Math.floor(this.samples.length / 2)]; | |
| return median; | |
| } | |
| printSummary() { | |
| print(`${this.name}:`); | |
| print(` Time (mean ± σ): ${this.mean().toFixed(3)}ms ± ${this.stddev().toFixed(3)}ms`); | |
| print(` Range (min … max): ${this.min().toFixed(3)}ms … ${this.max().toFixed(3)}ms`); | |
| } | |
| printSummaryCSV(includeHeaderRow = true) { | |
| if (includeHeaderRow) { | |
| print("mean,stddev,min,max"); | |
| } | |
| print(`${this.mean()},${this.stddev()},${this.min()},${this.max()}`); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment