Last active
May 23, 2023 13:53
-
-
Save scarf005/25ea81b8b67c7008f2d74c871eff7c20 to your computer and use it in GitHub Desktop.
This file contains 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
import { | |
bgBrightRed, | |
bold, | |
brightGreen, | |
brightRed, | |
brightWhite, | |
brightYellow, | |
} from "https://deno.land/std@0.186.0/fmt/colors.ts" | |
import { c, p } from "https://deno.land/x/copb@v1.0.1/mod.ts" | |
import { match } from "npm:ts-pattern" | |
const redBoldBg = c(p(bgBrightRed)(brightWhite)(bold)) | |
const color = (ms: number) => | |
match(ms) | |
.when((x) => x < 100, () => brightGreen) | |
.when((x) => x < 500, () => brightYellow) | |
.when((x) => x < 1000, () => brightRed) | |
.otherwise(() => redBoldBg) | |
const timeitInner = ({ start, end }: { start: number; end: number }) => { | |
const ms = Math.round(end - start) | |
const colorFn = color(ms) | |
return { ms, color: colorFn, msColored: colorFn(`(${ms}ms)`) } | |
} | |
/** wait for a promise and returns its value, time it took, and color. */ | |
export const timeitVerbose = async <T>(val: Promise<T>) => { | |
const start = performance.now() | |
const result = await val | |
const end = performance.now() | |
return { result, ...timeitInner({ start, end }) } | |
} | |
export const timeitSyncVerbose = <T>(fn: () => T) => { | |
const start = performance.now() | |
const result = fn() | |
const end = performance.now() | |
return { result, ...timeitInner({ start, end }) } | |
} | |
type TimeitOption<T> = { | |
name: string | ((val: T) => string) | |
val: Promise<T> | |
} | |
/** wait for a promise and log how long it took. */ | |
export const timeit = (quiet: boolean) => async <T>({ name, val }: TimeitOption<T>) => { | |
const { result, msColored } = await timeitVerbose(val) | |
const display = typeof name === "string" ? name : name(result) | |
if (!quiet) console.log(`${display} ${msColored}`) | |
return result | |
} | |
type TimeitSyncOption<T> = { | |
name: string | ((val: T) => string) | |
fn: () => T | |
} | |
export const timeitSync = (quiet: boolean) => <T>({ name, fn }: TimeitSyncOption<T>) => { | |
const { result, msColored } = timeitSyncVerbose(fn) | |
const display = typeof name === "string" ? name : name(result) | |
if (!quiet) console.log(`${display} ${msColored}`) | |
return result | |
} |
This file contains 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
import { timeitSyncVerbose } from "../timeit.ts" | |
type Pair<T, U> = { | |
f: (value: T) => U | |
log: (value: U) => string | |
} | |
type WithTime<T> = { | |
context: WithTimeCons<T> | |
map<U>({ f, log }: Pair<T, U>): WithTime<U> | |
get(): T | |
} | |
type WithTimeCons<T> = Readonly<{ | |
value: T | |
quiet: boolean | |
total: number | |
}> | |
class Timed<T> implements WithTime<T> { | |
constructor(public context: WithTimeCons<T>) {} | |
map<U>({ f, log }: Pair<T, U>): WithTime<U> { | |
const { result, ms, msColored } = timeitSyncVerbose(() => f(this.context.value)) | |
this.log(`${log(result)} ${msColored}`) | |
return new Timed({ value: result, quiet: this.context.quiet, total: this.context.total + ms }) | |
} | |
get(): T { | |
this.log(`total: ${this.context.total}ms`) | |
return this.context.value | |
} | |
private log(line: string) { | |
if (!this.context.quiet) { | |
console.log(line) | |
} | |
} | |
} | |
const withTimer = <T>({ value, quiet = false }: { value: T; quiet?: boolean }): WithTime<T> => | |
new Timed({ value, quiet, total: 0 }) | |
if (import.meta.main) { | |
const result = withTimer({ value: 1 }) | |
.map({ | |
f: (x) => x + 1, | |
log: (v) => `getting result ${v}`, | |
}) | |
.map({ | |
f: (x) => x * 2, | |
log: (v) => `multiplication result ${v}`, | |
}) | |
.get() | |
console.log(`result: ${result}`) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment