From 6f0a4638348ed20633d623ee973f9c9a96f65104 Mon Sep 17 00:00:00 2001 From: Oleksii Date: Wed, 16 Oct 2024 14:15:13 -0400 Subject: [PATCH] Add chalk v5 and yoctocolors to benchmarks (#88) * apply prettier conditionally * add chalk v5 and yoctocolors to benchmarks * node v6 build compat * fine, save --- .github/workflows/benchmarks.yaml | 8 ++- .prettierignore | 1 - benchmarks/complex.mjs | 32 ++++++++- benchmarks/loading.mjs | 75 ++++++++++++++++----- benchmarks/recursion.mjs | 13 +++- benchmarks/simple.mjs | 13 +++- benchmarks/size.mjs | 5 +- package.json | 6 +- picocolors.js | 107 ++++++++++++++---------------- tests/environments.js | 1 + tests/test.js | 47 ++++++------- 11 files changed, 200 insertions(+), 108 deletions(-) delete mode 100644 .prettierignore diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index 11a812e..140f717 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -23,11 +23,13 @@ jobs: run: node tests/environments.js - name: Install esbuild run: npm install esbuild + - name: Install missing libs + run: npm install chalk5@"npm:chalk@v5.x" - name: Simple API calls - run: node benchmarks/simple.mjs + run: node benchmarks/simple.mjs --expose-gc - name: Complex formatting expression - run: node benchmarks/complex.mjs + run: node benchmarks/complex.mjs --expose-gc - name: Library module's init time - run: node benchmarks/loading.mjs + run: node benchmarks/loading.mjs --expose-gc - name: Total loaded code size run: node benchmarks/size.mjs diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index a3fb561..0000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -picocolors.browser.* diff --git a/benchmarks/complex.mjs b/benchmarks/complex.mjs index 7d23c69..ee119bc 100644 --- a/benchmarks/complex.mjs +++ b/benchmarks/complex.mjs @@ -1,19 +1,22 @@ +/* @prettier */ import { run, bench, summary } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" +import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" +import * as yoctocolors from "yoctocolors" summary(() => { let index = 1e8 bench( - "chalk", + "chalk v4", () => chalk.red(".") + chalk.yellow(".") + @@ -24,6 +27,33 @@ summary(() => { ) ) + bench( + "chalk v5", + () => + chalk5.red(".") + + chalk5.yellow(".") + + chalk5.green(".") + + chalk5.bgRed(chalk5.black(" ERROR ")) + + chalk5.red( + " Add plugin " + chalk5.yellow("name") + " to use time limit with " + chalk5.yellow(++index) + ) + ) + + bench( + "yoctocolors", + () => + yoctocolors.red(".") + + yoctocolors.yellow(".") + + yoctocolors.green(".") + + yoctocolors.bgRed(yoctocolors.black(" ERROR ")) + + yoctocolors.red( + " Add plugin " + + yoctocolors.yellow("name") + + " to use time limit with " + + yoctocolors.yellow(++index) + ) + ) + bench( "cli-color", () => diff --git a/benchmarks/loading.mjs b/benchmarks/loading.mjs index dd8de23..19bfc71 100755 --- a/benchmarks/loading.mjs +++ b/benchmarks/loading.mjs @@ -1,3 +1,4 @@ +/* @prettier */ import { run, bench, group } from "mitata" import { buildSync } from "esbuild" import { createRequire } from "module" @@ -12,6 +13,8 @@ function build(contents) { bundle: true, write: false, platform: "node", + format: "cjs", + target: "es2020", stdin: { contents, loader: "js", resolveDir: root }, }) let code = result.outputFiles[0].text @@ -23,36 +26,76 @@ function compile(code, context) { } group(() => { - let codeP = build(`let picocolors = require("../picocolors.js")`) - let contextP = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeP = build( + `let picocolors = require("../picocolors.js"); console.log(picocolors != null);` + ) + let contextP = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("picocolors", () => compile(codeP, contextP)) - let codeAC = build(`let ansi = require("ansi-colors")`) - let contextAC = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeAC = build(`let ansi = require("ansi-colors"); console.log(ansi != null);`) + let contextAC = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("ansi-colors", () => compile(codeAC, contextAC)) - let codeK = build(`let kleur = require("kleur")`) - let contextK = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeK = build(`let kleur = require("kleur"); console.log(kleur != null);`) + let contextK = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("kleur", () => compile(codeK, contextK)) - let codeKC = build(`let kleurColors = require("kleur/colors")`) - let contextKC = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeKC = build(`let kleurColors = require("kleur/colors"); console.log(kleurColors != null);`) + let contextKC = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("kleur/colors", () => compile(codeKC, contextKC)) - let codeC = build(`let colorette = require("colorette")`) - let contextC = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeC = build(`let colorette = require("colorette"); console.log(colorette != null);`) + let contextC = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("colorette", () => compile(codeC, contextC)) - let codeN = build(`let nanocolors = require("nanocolors")`) - let contextN = createContext({ require: createRequire(filename), process: { env: {} } }) + let codeN = build(`let nanocolors = require("nanocolors"); console.log(nanocolors != null);`) + let contextN = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("nanocolors", () => compile(codeN, contextN)) - let codeCh = build(`let chalk = require("chalk")`) - let contextCh = createContext({ require: createRequire(filename), process: { env: {} } }) - bench("chalk", () => compile(codeCh, contextCh)) + let codeY = build(`import * as yoctocolors from "yoctocolors"; console.log(yoctocolors != null);`) + let contextY = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) + bench("yoctocolors", () => compile(codeY, contextY)) + + let codeCh = build(`let chalk = require("chalk"); console.log(chalk != null);`) + let contextCh = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) + bench("chalk v4", () => compile(codeCh, contextCh)) + + let codeCh5 = build(`import * as chalk5 from "chalk5"; console.log(chalk5 != null);`) + let contextCh5 = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) + bench("chalk v5", () => compile(codeCh5, contextCh5)) let codeCC = build(`let cliColor = require("cli-color")`) - let contextCC = createContext({ require: createRequire(filename), process: { env: {} } }) + let contextCC = createContext({ + require: createRequire(filename), + process: { env: { FORCE_COLOR: 1 } }, + }) bench("cli-color", () => compile(codeCC, contextCC)) }) diff --git a/benchmarks/recursion.mjs b/benchmarks/recursion.mjs index 47c6ba3..1f10a24 100644 --- a/benchmarks/recursion.mjs +++ b/benchmarks/recursion.mjs @@ -1,22 +1,29 @@ +/* @prettier */ import { run, bench, summary } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" +import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" +import * as yoctocolors from "yoctocolors" let count = 1000 let input = "lorem ipsum dolor sit amet" summary(() => { - bench("chalk", () => { + bench("chalk v4", () => { return chalk.blue(chalk.red(input).repeat(count)) }) + bench("chalk v5", () => { + return chalk5.blue(chalk5.red(input).repeat(count)) + }) + bench("cli-color", () => { return cliColor.blue(cliColor.red(input).repeat(count)) }) @@ -41,6 +48,10 @@ summary(() => { return nanocolors.blue(nanocolors.red(input).repeat(count)) }) + bench("yoctocolors", () => { + return yoctocolors.blue(yoctocolors.red(input).repeat(count)) + }) + bench("picocolors", () => { return picocolors.blue(picocolors.red(input).repeat(count)) }) diff --git a/benchmarks/simple.mjs b/benchmarks/simple.mjs index 9ee2dcd..9ca90e8 100644 --- a/benchmarks/simple.mjs +++ b/benchmarks/simple.mjs @@ -1,26 +1,34 @@ +/* @prettier */ import { run, bench, boxplot } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" +import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" +import * as yoctocolors from "yoctocolors" console.log(colorette.green("colorette")) console.log(kleur.green("kleur")) console.log(chalk.green("chalk")) +console.log(chalk5.green("chalk5")) console.log(ansi.green("ansi")) console.log(cliColor.green("cliColor")) console.log(picocolors.green("picocolors")) console.log(nanocolors.green("nanocolors")) +console.log(yoctocolors.green("yoctocolors")) boxplot(() => { - bench("chalk", () => { + bench("chalk v4", () => { return chalk.red("Add plugin to use time limit") }) + bench("chalk v5", () => { + return chalk5.red("Add plugin to use time limit") + }) bench("cli-color", () => { return cliColor.red("Add plugin to use time limit") }) @@ -39,6 +47,9 @@ boxplot(() => { bench("nanocolors", () => { return nanocolors.red("Add plugin to use time limit") }) + bench("yoctocolors", () => { + return yoctocolors.red("Add plugin to use time limit") + }) bench("picocolors", () => { return picocolors.red("Add plugin to use time limit") }) diff --git a/benchmarks/size.mjs b/benchmarks/size.mjs index b5b9ef8..80e207d 100644 --- a/benchmarks/size.mjs +++ b/benchmarks/size.mjs @@ -1,15 +1,18 @@ +/* @prettier */ import { buildSync } from "esbuild" import { dirname } from "node:path" console.table({ picocolors: build(`export { default as picocolors } from "../picocolors.js"`), colorette: build(`export * as colorette from "colorette"`), - chalk: build(`export { default as chalk } from "chalk"`), + "chalk v4": build(`export { default as chalk } from "chalk"`), + "chalk v5": build(`export * as chalk from "chalk5"`), kleur: build(`export { default as kleur } from "kleur"`), "kleur/colors": build(`export * as kleurColors from "kleur/colors"`), "ansi-colors": build(`export { default as ansi } from "ansi-colors"`), "cli-color": build(`export { default as cliColor } from "cli-color"`), nanocolors: build(`export * as nanocolors from "nanocolors"`), + yoctocolors: build(`export * as yoctocolors from "yoctocolors"`), }) function build(contents) { diff --git a/package.json b/package.json index e0042c3..ed91e87 100644 --- a/package.json +++ b/package.json @@ -34,14 +34,16 @@ "kleur": "^4.1.4", "mitata": "^1.0.10", "nanocolors": "^0.2.12", - "prettier": "^2.4.1" + "prettier": "^3.3.3", + "yoctocolors": "^2.1.1" }, "prettier": { "printWidth": 100, "useTabs": true, "tabWidth": 2, "semi": false, - "arrowParens": "avoid" + "arrowParens": "avoid", + "requirePragma": true }, "clean-publish": { "cleanDocs": true diff --git a/picocolors.js b/picocolors.js index 2dc32be..e32df85 100644 --- a/picocolors.js +++ b/picocolors.js @@ -1,27 +1,16 @@ -let p = process || {}, - argv = p.argv || [], - env = p.env || {} +let p = process || {}, argv = p.argv || [], env = p.env || {} let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && - (!!env.FORCE_COLOR || - argv.includes("--color") || - p.platform === "win32" || - ((p.stdout || {}).isTTY && env.TERM !== "dumb") || - !!env.CI) + (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI) -let formatter = - (open, close, replace = open) => +let formatter = (open, close, replace = open) => input => { - let string = "" + input - let index = string.indexOf(close, open.length) - return ~index - ? open + replaceClose(string, close, replace, index) + close - : open + string + close + let string = "" + input, index = string.indexOf(close, open.length) + return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close } let replaceClose = (string, close, replace, index) => { - let result = "" - let cursor = 0 + let result = "", cursor = 0 do { result += string.substring(cursor, index) + replace cursor = index + close.length @@ -31,54 +20,54 @@ let replaceClose = (string, close, replace, index) => { } let createColors = (enabled = isColorSupported) => { - let init = enabled ? formatter : () => String + let f = enabled ? formatter : () => String return { isColorSupported: enabled, - reset: init("\x1b[0m", "\x1b[0m"), - bold: init("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), - dim: init("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), - italic: init("\x1b[3m", "\x1b[23m"), - underline: init("\x1b[4m", "\x1b[24m"), - inverse: init("\x1b[7m", "\x1b[27m"), - hidden: init("\x1b[8m", "\x1b[28m"), - strikethrough: init("\x1b[9m", "\x1b[29m"), + reset: f("\x1b[0m", "\x1b[0m"), + bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), + dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), + italic: f("\x1b[3m", "\x1b[23m"), + underline: f("\x1b[4m", "\x1b[24m"), + inverse: f("\x1b[7m", "\x1b[27m"), + hidden: f("\x1b[8m", "\x1b[28m"), + strikethrough: f("\x1b[9m", "\x1b[29m"), - black: init("\x1b[30m", "\x1b[39m"), - red: init("\x1b[31m", "\x1b[39m"), - green: init("\x1b[32m", "\x1b[39m"), - yellow: init("\x1b[33m", "\x1b[39m"), - blue: init("\x1b[34m", "\x1b[39m"), - magenta: init("\x1b[35m", "\x1b[39m"), - cyan: init("\x1b[36m", "\x1b[39m"), - white: init("\x1b[37m", "\x1b[39m"), - gray: init("\x1b[90m", "\x1b[39m"), + black: f("\x1b[30m", "\x1b[39m"), + red: f("\x1b[31m", "\x1b[39m"), + green: f("\x1b[32m", "\x1b[39m"), + yellow: f("\x1b[33m", "\x1b[39m"), + blue: f("\x1b[34m", "\x1b[39m"), + magenta: f("\x1b[35m", "\x1b[39m"), + cyan: f("\x1b[36m", "\x1b[39m"), + white: f("\x1b[37m", "\x1b[39m"), + gray: f("\x1b[90m", "\x1b[39m"), - bgBlack: init("\x1b[40m", "\x1b[49m"), - bgRed: init("\x1b[41m", "\x1b[49m"), - bgGreen: init("\x1b[42m", "\x1b[49m"), - bgYellow: init("\x1b[43m", "\x1b[49m"), - bgBlue: init("\x1b[44m", "\x1b[49m"), - bgMagenta: init("\x1b[45m", "\x1b[49m"), - bgCyan: init("\x1b[46m", "\x1b[49m"), - bgWhite: init("\x1b[47m", "\x1b[49m"), + bgBlack: f("\x1b[40m", "\x1b[49m"), + bgRed: f("\x1b[41m", "\x1b[49m"), + bgGreen: f("\x1b[42m", "\x1b[49m"), + bgYellow: f("\x1b[43m", "\x1b[49m"), + bgBlue: f("\x1b[44m", "\x1b[49m"), + bgMagenta: f("\x1b[45m", "\x1b[49m"), + bgCyan: f("\x1b[46m", "\x1b[49m"), + bgWhite: f("\x1b[47m", "\x1b[49m"), - blackBright: init("\x1b[90m", "\x1b[39m"), - redBright: init("\x1b[91m", "\x1b[39m"), - greenBright: init("\x1b[92m", "\x1b[39m"), - yellowBright: init("\x1b[93m", "\x1b[39m"), - blueBright: init("\x1b[94m", "\x1b[39m"), - magentaBright: init("\x1b[95m", "\x1b[39m"), - cyanBright: init("\x1b[96m", "\x1b[39m"), - whiteBright: init("\x1b[97m", "\x1b[39m"), + blackBright: f("\x1b[90m", "\x1b[39m"), + redBright: f("\x1b[91m", "\x1b[39m"), + greenBright: f("\x1b[92m", "\x1b[39m"), + yellowBright: f("\x1b[93m", "\x1b[39m"), + blueBright: f("\x1b[94m", "\x1b[39m"), + magentaBright: f("\x1b[95m", "\x1b[39m"), + cyanBright: f("\x1b[96m", "\x1b[39m"), + whiteBright: f("\x1b[97m", "\x1b[39m"), - bgBlackBright: init("\x1b[100m", "\x1b[49m"), - bgRedBright: init("\x1b[101m", "\x1b[49m"), - bgGreenBright: init("\x1b[102m", "\x1b[49m"), - bgYellowBright: init("\x1b[103m", "\x1b[49m"), - bgBlueBright: init("\x1b[104m", "\x1b[49m"), - bgMagentaBright: init("\x1b[105m", "\x1b[49m"), - bgCyanBright: init("\x1b[106m", "\x1b[49m"), - bgWhiteBright: init("\x1b[107m", "\x1b[49m"), + bgBlackBright: f("\x1b[100m", "\x1b[49m"), + bgRedBright: f("\x1b[101m", "\x1b[49m"), + bgGreenBright: f("\x1b[102m", "\x1b[49m"), + bgYellowBright: f("\x1b[103m", "\x1b[49m"), + bgBlueBright: f("\x1b[104m", "\x1b[49m"), + bgMagentaBright: f("\x1b[105m", "\x1b[49m"), + bgCyanBright: f("\x1b[106m", "\x1b[49m"), + bgWhiteBright: f("\x1b[107m", "\x1b[49m"), } } diff --git a/tests/environments.js b/tests/environments.js index 8ac23ca..537cdb9 100644 --- a/tests/environments.js +++ b/tests/environments.js @@ -1,3 +1,4 @@ +/* @prettier */ let vm = require("vm") let fs = require("fs") let pc = require("../picocolors.js") diff --git a/tests/test.js b/tests/test.js index 7addfa7..37ad6ac 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,3 +1,4 @@ +/* @prettier */ let pc = require("../picocolors.js") let assert = require("assert") @@ -31,22 +32,22 @@ const FMT = { bgWhite: ["\x1b[47m", "\x1b[49m"], blackBright: ["\x1b[90m", "\x1b[39m"], - redBright: ["\x1b[91m", "\x1b[39m"], - greenBright: ["\x1b[92m", "\x1b[39m"], - yellowBright: ["\x1b[93m", "\x1b[39m"], - blueBright: ["\x1b[94m", "\x1b[39m"], - magentaBright: ["\x1b[95m", "\x1b[39m"], - cyanBright: ["\x1b[96m", "\x1b[39m"], - whiteBright: ["\x1b[97m", "\x1b[39m"], - - bgBlackBright: ["\x1b[100m","\x1b[49m"], - bgRedBright: ["\x1b[101m","\x1b[49m"], - bgGreenBright: ["\x1b[102m","\x1b[49m"], - bgYellowBright: ["\x1b[103m","\x1b[49m"], - bgBlueBright: ["\x1b[104m","\x1b[49m"], - bgMagentaBright: ["\x1b[105m","\x1b[49m"], - bgCyanBright: ["\x1b[106m","\x1b[49m"], - bgWhiteBright: ["\x1b[107m","\x1b[49m"], + redBright: ["\x1b[91m", "\x1b[39m"], + greenBright: ["\x1b[92m", "\x1b[39m"], + yellowBright: ["\x1b[93m", "\x1b[39m"], + blueBright: ["\x1b[94m", "\x1b[39m"], + magentaBright: ["\x1b[95m", "\x1b[39m"], + cyanBright: ["\x1b[96m", "\x1b[39m"], + whiteBright: ["\x1b[97m", "\x1b[39m"], + + bgBlackBright: ["\x1b[100m", "\x1b[49m"], + bgRedBright: ["\x1b[101m", "\x1b[49m"], + bgGreenBright: ["\x1b[102m", "\x1b[49m"], + bgYellowBright: ["\x1b[103m", "\x1b[49m"], + bgBlueBright: ["\x1b[104m", "\x1b[49m"], + bgMagentaBright: ["\x1b[105m", "\x1b[49m"], + bgCyanBright: ["\x1b[106m", "\x1b[49m"], + bgWhiteBright: ["\x1b[107m", "\x1b[49m"], } test("color matching", () => { @@ -157,13 +158,13 @@ test("non-string input", () => { }) test("shouldn't overflow when coloring already colored large text", () => { - try { - pc.blue(pc.red("x").repeat(10000)) - assert(true) - } catch (error){ - console.error(error) - assert(false) - } + try { + pc.blue(pc.red("x").repeat(10000)) + assert(true) + } catch (error) { + console.error(error) + assert(false) + } }) function test(name, fn) {