UNPKG

@monstermann/tinybench-pretty-printer

Version:
411 lines (392 loc) 12.1 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { TinybenchPrinterImpl: () => TinybenchPrinterImpl, tinybenchPrinter: () => tinybenchPrinter }); module.exports = __toCommonJS(src_exports); // src/tinybenchPrinter.ts var import_tables = require("@monstermann/tables"); // src/columns/name.ts function name(options = {}) { return { header: options?.header ?? "name", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? "left", rowStyle: options?.rowStyle ?? [], content({ task }) { return task.name; } }; } // src/columns/summary.ts function summary(options = {}) { const method = options.method ?? "%"; const fastestTitle = options.fastestTitle || "\u{1F947}"; return { header: options?.header ?? "summary", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? (method === "%" ? "center" : "right"), rowStyle: options?.rowStyle ?? [], content({ task, fastestTask, formatNumber: formatNumber2 }) { const fastestHz = fastestTask.result.hz; const hz = task.result.hz; if (hz === fastestHz) return fastestTitle; switch (method) { case "x": return `${formatNumber2(fastestHz / hz)}x slower`; case "%": return `${formatNumber2((hz - fastestHz) / fastestHz * 100)}%`; default: return ""; } } }; } // src/columns/ops.ts function ops(options = {}) { return { header: options?.header ?? "ops/sec", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? "right", rowStyle: options?.rowStyle ?? ["blue"], content({ task, tasks, formatCount }) { return formatCount( options.method ?? "shortest", task.result.hz, tasks.map((task2) => task2.result.hz) ); } }; } // src/columns/time.ts function time(options = {}) { return { header: options?.header ?? "time/op", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? "right", rowStyle: options?.rowStyle ?? ["yellow"], content({ task, tasks, formatDuration }) { return formatDuration( options.method ?? "shortest", task.result.mean, tasks.map((task2) => task2.result.mean) ); } }; } // src/columns/margin.ts function margin(options = {}) { return { header: options?.header ?? "margin", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? "center", rowStyle: options?.rowStyle ?? ["magenta"], content({ task, locales }) { return `\xB1${task.result.rme.toLocaleString(locales, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%`; } }; } // src/columns/samples.ts function samples(options = {}) { return { header: options?.header ?? "samples", headerStyle: options?.headerStyle ?? ["bold"], headerAlignment: options?.headerAlignment ?? "center", rowAlignment: options?.rowAlignment ?? "right", rowStyle: options?.rowStyle ?? ["magenta"], content({ task, tasks, formatCount }) { return formatCount( options.method ?? "shortest", task.result.samples.length, tasks.map((task2) => task2.result.samples.length) ); } }; } // src/helpers/sortTasks.ts function sortTasks(tasks, method) { switch (method) { case false: return tasks; case void 0: return tasks.sort((a, b) => b.result.hz - a.result.hz); case "asc": return tasks.sort((a, b) => a.result.hz - b.result.hz); case "desc": return tasks.sort((a, b) => b.result.hz - a.result.hz); default: return method(tasks); } } // src/helpers/mapRecord.ts function mapRecord(record, map) { const entries = Object.entries(record); const mappedEntries = entries.map(([name2, value]) => [name2, map(value, name2)]); return Object.fromEntries(mappedEntries); } // src/helpers/getFastestTask.ts function getFastestTask(tasks) { const [first] = tasks; return first ? tasks.reduce((a, b) => a.result.hz < b.result.hz ? b : a, first) : void 0; } // src/helpers/getSlowestTask.ts function getSlowestTask(tasks) { const [first] = tasks; return first ? tasks.reduce((a, b) => a.result.hz < b.result.hz ? a : b, first) : void 0; } // src/helpers/formatNumber.ts function formatNumber(value, locales) { return value.toLocaleString(locales, getPrecision(value)); } function getPrecision(value) { if (value < 1) return { maximumSignificantDigits: 2 }; if (value < 10) return { maximumSignificantDigits: 1 }; return { maximumFractionDigits: 0 }; } // src/helpers/createNumberFormatter.ts var createNumberFormatter = (locales) => (value) => formatNumber(value, locales); // src/helpers/mean.ts function mean(values) { return values.reduce((a, b) => a + b, 0) / values.length; } // src/helpers/createDurationFormatter.ts function createDurationFormatter(locales) { return function formatDuration(method, value, values) { switch (method) { case "shortest": return formatDuration(resolveMethod(value), value, values); case "highest": return formatDuration(resolveMethod(Math.max(...values)), value, values); case "lowest": return formatDuration(resolveMethod(Math.min(...values)), value, values); case "mean": return formatDuration(resolveMethod(mean(values)), value, values); case "nanoseconds": return `${formatNumber(value * 1e6, locales)}ns`; case "microseconds": return `${formatNumber(value * 1e3, locales)}\xB5s`; case "milliseconds": return `${formatNumber(value, locales)}ms`; case "seconds": return `${formatNumber(value / 1e3, locales)}s `; } }; } function resolveMethod(ms) { if (ms / 1e3 >= 1) return "seconds"; if (ms >= 1) return "milliseconds"; if (ms * 1e3 >= 1) return "microseconds"; return "nanoseconds"; } // src/helpers/createCountFormatter.ts function createCountFormatter(locales) { return function formatCount(method, value, values) { switch (method) { case "none": return `${formatNumber(value, locales)} `; case "shortest": return formatCount(resolveMethod2(value), value, values); case "highest": return formatCount(resolveMethod2(Math.max(...values)), value, values); case "lowest": return formatCount(resolveMethod2(Math.min(...values)), value, values); case "mean": return formatCount(resolveMethod2(mean(values)), value, values); case "thousands": return `${formatNumber(value / 1e3, locales)}K`; case "millions": return `${formatNumber(value / 1e6, locales)}M`; case "billions": return `${formatNumber(value / 1e9, locales)}B`; } }; } function resolveMethod2(value) { if (value >= 1e9) return "billions"; if (value >= 1e6) return "millions"; if (value >= 1e3) return "thousands"; return "none"; } // src/tinybenchPrinter.ts var TinybenchPrinterImpl = class _TinybenchPrinterImpl { config; constructor(config) { this.config = config; } merge(config) { return new _TinybenchPrinterImpl({ ...this.config, ...config }); } order(order) { return this.merge({ order }); } column(name2, column) { return this.merge({ columns: { ...this.config.columns, [name2]: column } }); } name(options) { return this.column("name", name(options)); } summary(options) { return this.column("summary", summary(options)); } ops(options) { return this.column("ops", ops(options)); } time(options) { return this.column("time", time(options)); } margin(options) { return this.column("margin", margin(options)); } samples(options) { return this.column("samples", samples(options)); } locales(locales) { return this.merge({ locales }); } sort(sort) { return this.merge({ sort }); } maxWidth(maxWidth) { return this.merge({ maxWidth }); } stdout(stdout) { return this.merge({ stdout }); } padding(padding) { return this.merge({ padding }); } borders(borders) { return this.merge({ borders }); } borderStyle(borderStyle) { return this.merge({ borderStyle }); } useHeader(useHeader) { return this.merge({ useHeader }); } useTopBorder(useTopBorder) { return this.merge({ useTopBorder }); } useBottomBorder(useBottomBorder) { return this.merge({ useBottomBorder }); } useLeftBorder(useLeftBorder) { return this.merge({ useLeftBorder }); } useRightBorder(useRightBorder) { return this.merge({ useRightBorder }); } useDividerBorder(useDividerBorder) { return this.merge({ useDividerBorder }); } useHeaderSeparator(useHeaderSeparator) { return this.merge({ useHeaderSeparator }); } useRowSeparator(useRowSeparator) { return this.merge({ useRowSeparator }); } prepareTableConfig(bench) { const { sort, locales, columns, order, ...rest } = this.config; let tasks = bench.tasks.filter((task) => !!task.result).filter((task) => !task.result.error); if (!tasks.length) return; tasks = sortTasks(tasks, sort); const fastestTask = getFastestTask(tasks); const slowestTask = getSlowestTask(tasks); const formatNumber2 = createNumberFormatter(locales); const formatDuration = createDurationFormatter(locales); const formatCount = createCountFormatter(locales); const rows = tasks.map((task) => mapRecord(columns, (column) => column.content({ task, tasks, fastestTask, slowestTask, formatNumber: formatNumber2, formatDuration, formatCount, locales }))); return { ...rest, rows, columns: order, headerTitles: mapRecord(columns, (column) => column.header), headerAlignments: mapRecord(columns, (column) => column.headerAlignment), headerStyles: mapRecord(columns, (column) => column.headerStyle), columnAlignments: mapRecord(columns, (column) => column.rowAlignment), columnStyles: mapRecord(columns, (column) => column.rowStyle) }; } toCli(bench) { const config = this.prepareTableConfig(bench); if (!config) return ""; return import_tables.cli.createTable(config); } toMarkdown(bench) { const config = this.prepareTableConfig(bench); if (!config) return ""; return import_tables.markdown.createTable(config); } }; var tinybenchPrinter = new TinybenchPrinterImpl({ order: ["name", "summary", "ops", "time", "margin", "samples"], columns: { name: name(), summary: summary(), ops: ops(), time: time(), margin: margin(), samples: samples() } }); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { TinybenchPrinterImpl, tinybenchPrinter });