Skip to content

Instantly share code, notes, and snippets.

@BioPhoton
Last active August 23, 2025 02:36
Show Gist options
  • Select an option

  • Save BioPhoton/4af1e2838cdc9f0340d72b08fca225f1 to your computer and use it in GitHub Desktop.

Select an option

Save BioPhoton/4af1e2838cdc9f0340d72b08fca225f1 to your computer and use it in GitHub Desktop.

Revisions

  1. BioPhoton revised this gist Aug 23, 2025. 1 changed file with 266 additions and 410 deletions.
    676 changes: 266 additions & 410 deletions ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # ESLint Concurrency Benchmark (compact)
    # ESLint Concurrency Benchmark

    ## Overview
    - Benchmarks ESLint v9.34+ `--concurrency` across one or more targets
    @@ -9,11 +9,7 @@
    ## Defaults
    - **concurrency**: `off,4,8,auto`
    - **runs**: `3`
    - **outDir**: `tools/eslint-perf/results`

    > Note:
    > - `bench.compact.ts` defaults: uses `<target>/eslint.config.js` if present and lints TypeScript files under `<target>`.
    > - `bench.ts` supports custom patterns via `--patterns` and will default to `<target>/**/*.ts` and auto-use `<target>/eslint.config.js` if present when `--patterns` is not provided.
    - **outDir**: `./eslint-perf`

    ## Flags
    - `--targets=dir[,dir...]`: Comma-separated target directories
    @@ -26,33 +22,34 @@
    ## Examples
    - Minimal (defaults):
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts
    node --import tsx bench.ts
    ```

    - Custom targets + concurrency:
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts \
    node --import tsx bench.ts \
    --targets=packages/lib-a,packages/lib-b \
    --concurrency=off,2,4,auto \
    --runs=5
    ```

    - Custom patterns (bench.ts):
    ```bash
    node --import tsx tools/eslint-perf/bench.ts \
    node --import tsx bench.ts \
    --targets=packages/lib-a \
    --patterns="packages/lib-a/**/*.ts,packages/lib-a/**/*.tsx" \
    --concurrency=off,4,auto
    ```

    ## Output
    - **Raw JSON**: `tools/eslint-perf/results/system-info-*.json` and `eslint-benchmark-*.json`
    - **Summary**: `tools/eslint-perf/results/*.summary.md`
    - **Raw JSON**: `./eslint-perf/system-info-*.json` and `./eslint-perf/eslint-benchmark-*.json`
    - **Summary**: `./eslint-perf/*.summary.md`
    - **Terminal**: fastest table + per-target breakdown (★ marks best)

    ### Output Example
    ```bash
    > node --import tsx tools/eslint-perf/bench.ts --targets=packages/lib-a --concurrency=off,1,2,4,6,8,auto --runs=3 --verbose
    > node --import tsx tools/eslint-perf/
    --targets=packages/lib-a --concurrency=off,1,2,4,6,8,auto --runs=3 --verbose

    📁 Target: packages/lib-a (files: 106, ts: 101, js: 5)
    🔧 Concurrency: off
    @@ -65,7 +62,7 @@ node --import tsx tools/eslint-perf/bench.ts \

    ✅ Benchmark complete
    Raw results: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.json
    Summary: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.summary.md
    Summary: ./eslint-perf/eslint-benchmark-2025-08-23T01-39-46-558Z.summary.md

    Fastest per target:
    Target Best Avg(s) Baseline(s) Speedup
    @@ -86,18 +83,29 @@ off 8.849 0.078 1.00x ★
    auto 9.490 0.095 0.93x
    ```

    # CPU Measures
    # CPU Measures

    ```bash
    npx @push-based/cpu-prof@latest npx eslint . --concurrency=4
    # Profile CPU usage while running ESLint with explicit config and patterns
    npx @push-based/cpu-prof@latest -- \
    npx eslint -c packages/lib-a/eslint.config.js \
    "packages/lib-a/**/*.ts" \
    --concurrency=4
    ```

    What this does:
    - Starts ESLint with Node CPU profiling enabled and collects .cpuprofile files
    - Merges them into a single Chrome trace JSON for easy inspection

    Expected output:
    - Profiles folder: `./profiles` (or a printed absolute path)
    - Individual `.cpuprofile` files for the run
    - Merged trace JSON like `Trace-<timestamp>.json`
    - Open the merged JSON in Chrome DevTools → Performance → Load profile to view threads, tasks, and CPU usage with `--concurrency=4`

    # bench.ts

    ```ts
    /*
    * ESLint Concurrency Benchmark Suite
    * Runs ESLint with multiple concurrency settings across selected targets,
    * collects timings and quantitative data, and writes structured results.
    */
    import { exec as execCb } from 'node:child_process';
    import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';
    import os from 'node:os';
    @@ -106,17 +114,16 @@ import { promisify } from 'node:util';

    const exec = promisify(execCb);

    type Concurrency = 'off' | 'auto' | `${number}`;

    type BenchmarkRun = {
    type C = 'off' | 'auto' | `${number}`;
    type Run = {
    target: string;
    concurrency: Concurrency;
    concurrency: C;
    run: number;
    timing: {
    durationSeconds: number;
    realTimeSeconds: number | null;
    userTimeSeconds: number | null;
    sysTimeSeconds: number | null;
    realTimeSeconds: null;
    userTimeSeconds: null;
    sysTimeSeconds: null;
    };
    eslintResults: {
    filesProcessed: number;
    @@ -126,295 +133,194 @@ type BenchmarkRun = {
    };
    timestamp: string;
    };

    type BenchmarkStats = {
    avg: number;
    type Stats = {
    runs: number;
    min: number;
    max: number;
    avg: number;
    stdDev: number;
    runs: number;
    };

    type TargetInfo = {
    type TI = {
    target: string;
    tsFiles: number;
    jsFiles: number;
    totalFiles: number;
    };

    type SuiteResult = {
    target: string;
    targetInfo: TargetInfo;
    concurrency: Concurrency;
    statistics: BenchmarkStats;
    runs: BenchmarkRun[];
    };

    type SystemInfo = {
    timestamp: string;
    system: {
    os: string;
    osVersion: string;
    architecture: string;
    cpuCores: number;
    totalMemGb: number;
    hostname: string;
    };
    software: {
    nodeVersion: string;
    npmVersion: string;
    eslintVersion: string;
    nxVersion: string | null;
    };
    };

    // -----------------------------
    // Config via CLI args (minimal)
    // -----------------------------
    const DEFAULT_TARGETS = [
    const DFLT_TARGETS = [
    'packages/models',
    'packages/plugin-eslint',
    'packages/cli',
    'packages/core',
    'packages/utils',
    ];
    const DEFAULT_CONCURRENCY: Concurrency[] = [
    'off',
    '1',
    '2',
    '4',
    '6',
    '8',
    'auto',
    ];
    const DEFAULT_RUNS = 3;

    function parseArgs() {
    const args = process.argv.slice(2);
    const getArg = (name: string): string | undefined => {
    const prefix = `--${name}=`;
    return args.find(a => a.startsWith(prefix))?.slice(prefix.length);
    };

    const targets =
    getArg('targets')?.split(',').filter(Boolean) ?? DEFAULT_TARGETS;
    const conc = getArg('concurrency')?.split(',').filter(Boolean) as
    | Concurrency[]
    | undefined;
    const concurrency = conc && conc.length > 0 ? conc : DEFAULT_CONCURRENCY;
    const runs = Number.parseInt(getArg('runs') ?? `${DEFAULT_RUNS}`, 10);
    const outDir =
    getArg('outDir') ?? path.join('tools', 'eslint-perf', 'results');

    const verbose = args.includes('--verbose') || getArg('verbose') === 'true';
    const patterns = getArg('patterns')
    ?.split(',')
    .map(p => p.trim())
    .filter(Boolean);

    return {
    targets,
    concurrency,
    runs,
    outDir,
    verbose,
    patterns,
    };
    }

    // -----------------------------
    // Utilities
    // -----------------------------
    async function pathExists(p: string): Promise<boolean> {
    try {
    await stat(p);
    return true;
    } catch {
    return false;
    }
    const DFLT_CONC: C[] = ['off', '4', '8', 'auto'];
    const DFLT_RUNS = 3;
    const pad = (s: string, n: number) =>
    s.length >= n ? s : s + ' '.repeat(n - s.length);
    const exists = async (p: string) => !!(await stat(p).catch(() => null));
    const ensureDir = (d: string) => mkdir(d, { recursive: true });

    function args() {
    const a = process.argv.slice(2);
    const get = (n: string) =>
    a.find(x => x.startsWith(`--${n}=`))?.split('=')[1];
    const targets = get('targets')?.split(',').filter(Boolean) ?? DFLT_TARGETS;
    const conc =
    (get('concurrency')?.split(',').filter(Boolean) as C[] | undefined) ??
    DFLT_CONC;
    const runs = Number.parseInt(get('runs') ?? `${DFLT_RUNS}`, 10);
    const outDir = get('outDir') ?? path.join('tools', 'eslint-perf', 'results');
    const verbose = a.includes('--verbose') || get('verbose') === 'true';
    const useLocalConfig = get('useLocalConfig') === 'false' ? false : true;
    const tsOnly = get('tsOnly') === 'false' ? false : true;
    return { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly };
    }

    async function collectSystemInfo(): Promise<SystemInfo> {
    const cpuCores = os.cpus()?.length ?? 0;
    const totalMemGb = Math.round((os.totalmem() / 1024 ** 3) * 100) / 100;
    const nodeVersion = process.version;
    const npmVersion = (await exec('npm --version')).stdout.trim();
    const eslintVersion = (await exec('npx eslint --version')).stdout.trim();
    let nxVersion: string | null = null;
    try {
    nxVersion =
    (await exec('npx nx --version')).stdout.trim().split('\n')[0] ?? null;
    } catch {
    nxVersion = null;
    }

    async function sys() {
    const nx = await exec('npx nx --version')
    .then(r => r.stdout.trim().split('\n')[0])
    .catch(() => null);
    return {
    timestamp: new Date().toISOString(),
    system: {
    os: os.platform(),
    osVersion: os.release(),
    architecture: os.arch(),
    cpuCores,
    totalMemGb,
    cpuCores: os.cpus()?.length ?? 0,
    totalMemGb: Math.round((os.totalmem() / 1024 ** 3) * 100) / 100,
    hostname: os.hostname(),
    },
    software: {
    nodeVersion,
    npmVersion,
    eslintVersion,
    nxVersion,
    nodeVersion: process.version,
    npmVersion: (await exec('npm --version')).stdout.trim(),
    eslintVersion: (await exec('npx eslint --version')).stdout.trim(),
    nxVersion: nx,
    },
    };
    }

    async function walkCountFiles(
    dir: string,
    extensions: string[],
    ): Promise<number> {
    let count = 0;
    async function walk(current: string): Promise<void> {
    const entries = await readdir(current, { withFileTypes: true });
    for (const entry of entries) {
    const p = path.join(current, entry.name);
    if (entry.isDirectory()) {
    if (
    entry.name === 'node_modules' ||
    entry.name === 'dist' ||
    entry.name === 'coverage'
    )
    continue;
    await walk(p);
    } else if (entry.isFile()) {
    if (extensions.some(ext => entry.name.endsWith(ext))) count += 1;
    }
    async function count(dir: string, exts: string[]) {
    let n = 0;
    const w = async (d: string): Promise<void> => {
    const es = await readdir(d, { withFileTypes: true });
    for (const e of es) {
    const p = path.join(d, e.name);
    if (e.isDirectory()) {
    if (['node_modules', 'dist', 'coverage'].includes(e.name)) continue;
    await w(p);
    } else if (e.isFile() && exts.some(ext => e.name.endsWith(ext))) n++;
    }
    }
    await walk(dir);
    return count;
    }

    async function analyzeTarget(target: string): Promise<TargetInfo> {
    const abs = path.resolve(target);
    const tsFiles = (await pathExists(abs))
    ? await walkCountFiles(abs, ['.ts', '.tsx'])
    : 0;
    const jsFiles = (await pathExists(abs))
    ? await walkCountFiles(abs, ['.js', '.jsx', '.mjs', '.cjs'])
    : 0;
    return {
    target,
    tsFiles,
    jsFiles,
    totalFiles: tsFiles + jsFiles,
    };
    await w(dir);
    return n;
    }

    function buildEslintCommand(
    concurrency: Concurrency,
    options: { patterns: string[]; json: boolean; configPath?: string },
    ): string {
    const configArg = options.configPath
    ? ` --config=${JSON.stringify(options.configPath)}`
    : '';
    const patternArgs = options.patterns.map(p => JSON.stringify(p)).join(' ');
    const formatArg = options.json ? '--format=json' : '--format=stylish';
    return `npx eslint${configArg} --concurrency=${concurrency} ${formatArg} ${patternArgs}`;
    async function info(t: string): Promise<TE> {
    const abs = path.resolve(t);
    if (!(await exists(abs)))
    return { target: t, tsFiles: 0, jsFiles: 0, totalFiles: 0 };
    const ts = await count(abs, ['.ts', '.tsx']);
    const js = await count(abs, ['.js', '.jsx', '.mjs', '.cjs']);
    return { target: t, tsFiles: ts, jsFiles: js, totalFiles: ts + js };
    }

    async function runESLintOnce(
    target: string,
    concurrency: Concurrency,
    run: number,
    verbose = false,
    patterns: string[],
    configPath?: string,
    ): Promise<BenchmarkRun> {
    const start = process.hrtime.bigint();
    const cmd = buildEslintCommand(concurrency, {
    patterns,
    json: true,
    configPath,
    });
    let stdout = '';
    let stderr = '';
    type TE = TI;

    const cmd = (
    t: string,
    c: C,
    o: { local: boolean; ts: boolean; json: boolean },
    ) =>
    `npx eslint${o.local ? ` --config=${JSON.stringify(path.join(t, 'eslint.config.js'))}` : ''} --concurrency=${c} ${o.json ? '--format=json' : '--format=stylish'} ${[o.ts ? path.join(t, '**', '*.ts') : t].map(p => JSON.stringify(p)).join(' ')}`;

    async function once(
    t: string,
    c: C,
    i: number,
    v: boolean,
    local: boolean,
    ts: boolean,
    ): Promise<Run> {
    const s = process.hrtime.bigint();
    const k = cmd(t, c, { local, ts, json: true });
    let out = '',
    err = '';
    try {
    const result = await exec(cmd, { maxBuffer: 1024 * 1024 * 200 });
    stdout = result.stdout;
    stderr = result.stderr;
    const r = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    out = r.stdout;
    err = r.stderr;
    } catch (e: any) {
    stdout = e.stdout ?? '';
    stderr = e.stderr ?? '';
    out = e.stdout ?? '';
    err = e.stderr ?? '';
    }
    if (verbose) {
    console.log(` $ ${cmd}`);
    if (stderr.trim()) {
    if (v) {
    console.log(` $ ${k}`);
    if (err.trim()) {
    console.log(' [stderr]');
    console.log(
    stderr
    err
    .split('\n')
    .map(l => ` ${l}`)
    .join('\n'),
    );
    }
    }
    const end = process.hrtime.bigint();
    const durationSeconds = Number(end - start) / 1_000_000_000;

    // Parse JSON output
    let filesProcessed = 0;
    let errors = 0;
    let warnings = 0;
    const d = Number(process.hrtime.bigint() - s) / 1_000_000_000;
    let files = 0,
    errors = 0,
    warnings = 0;
    try {
    const json = JSON.parse(stdout) as Array<{
    const j = JSON.parse(out) as Array<{
    errorCount: number;
    warningCount: number;
    }>;
    filesProcessed = json.length;
    for (const r of json) {
    files = j.length;
    for (const r of j) {
    errors += r.errorCount || 0;
    warnings += r.warningCount || 0;
    }
    } catch {
    // ignore parse errors
    }

    const eslintWarnings: string[] = [];
    if (stderr.includes('ESLintPoorConcurrencyWarning'))
    eslintWarnings.push('ESLintPoorConcurrencyWarning');

    } catch {}
    const warns = err.includes('ESLintPoorConcurrencyWarning')
    ? ['ESLintPoorConcurrencyWarning']
    : [];
    return {
    target,
    concurrency,
    run,
    target: t,
    concurrency: c,
    run: i,
    timing: {
    durationSeconds,
    durationSeconds: d,
    realTimeSeconds: null,
    userTimeSeconds: null,
    sysTimeSeconds: null,
    },
    eslintResults: {
    filesProcessed,
    filesProcessed: files,
    errors,
    warnings,
    eslintWarnings,
    eslintWarnings: warns,
    },
    timestamp: new Date().toISOString(),
    };
    }

    async function printStylishOutputOnce(
    patterns: string[],
    configPath?: string,
    ): Promise<void> {
    const cmdStylish = buildEslintCommand('off', {
    patterns,
    json: false,
    configPath,
    });
    const statz = (xs: number[]): Stats => {
    const n = xs.length,
    min = Math.min(...xs),
    max = Math.max(...xs),
    avg = xs.reduce((a, b) => a + b, 0) / n,
    sd = Math.sqrt(xs.reduce((a, v) => a + (v - avg) ** 2, 0) / n);
    return {
    runs: n,
    min,
    max,
    avg: Number(avg.toFixed(3)),
    stdDev: Number(sd.toFixed(3)),
    };
    };

    async function stylish(t: string) {
    const k = cmd(t, 'off', { local: true, ts: true, json: false });
    try {
    const { stdout, stderr } = await exec(cmdStylish, {
    maxBuffer: 1024 * 1024 * 200,
    });
    const { stdout, stderr } = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    if (stdout.trim()) {
    console.log(' [stylish output]');
    console.log(
    @@ -435,22 +341,22 @@ async function printStylishOutputOnce(
    );
    }
    } catch (e: any) {
    const out = e.stdout ?? '';
    const err = e.stderr ?? '';
    if (out.trim()) {
    const o = e.stdout ?? '',
    er = e.stderr ?? '';
    if (o.trim()) {
    console.log(' [stylish output]');
    console.log(
    out
    o
    .split('\n')
    .slice(0, 300)
    .map((l: string) => ` ${l}`)
    .join('\n'),
    );
    }
    if (err.trim()) {
    if (er.trim()) {
    console.log(' [stylish stderr]');
    console.log(
    err
    er
    .split('\n')
    .map((l: string) => ` ${l}`)
    .join('\n'),
    @@ -459,205 +365,155 @@ async function printStylishOutputOnce(
    }
    }

    function statsFrom(values: number[]): BenchmarkStats {
    const runs = values.length;
    const min = Math.min(...values);
    const max = Math.max(...values);
    const avg = values.reduce((a, b) => a + b, 0) / runs;
    const variance = values.reduce((acc, v) => acc + (v - avg) ** 2, 0) / runs;
    const stdDev = Math.sqrt(variance);
    return {
    runs,
    min,
    max,
    avg: Number(avg.toFixed(3)),
    stdDev: Number(stdDev.toFixed(3)),
    };
    }

    async function ensureDir(dir: string): Promise<void> {
    await mkdir(dir, { recursive: true });
    }

    async function main(): Promise<void> {
    const { targets, concurrency, runs, outDir, verbose, patterns } = parseArgs();
    await ensureDir(outDir);

    const systemInfo = await collectSystemInfo();
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const resultsPath = path.join(outDir, `eslint-benchmark-${timestamp}.json`);
    const summaryPath = path.join(
    outDir,
    `eslint-benchmark-${timestamp}.summary.txt`,
    );

    const suiteResults: SuiteResult[] = [];

    // Write system info immediately
    async function main() {
    const { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly } =
    args();
    await ensureDir(outDir);
    const si = await sys(),
    ts = new Date().toISOString().replace(/[:.]/g, '-');
    const resPath = path.join(outDir, `eslint-benchmark-${ts}.json`),
    sumPath = path.join(outDir, `eslint-benchmark-${ts}.summary.md`);
    const results: any[] = [];
    await writeFile(
    path.join(outDir, `system-info-${timestamp}.json`),
    JSON.stringify(systemInfo, null, 2),
    path.join(outDir, `system-info-${ts}.json`),
    JSON.stringify(si, null, 2),
    );

    for (const target of targets) {
    const absTarget = path.resolve(target);
    if (!(await pathExists(absTarget))) {
    console.warn(`Skipping missing target: ${target}`);
    for (const t of targets) {
    if (!(await exists(path.resolve(t)))) {
    console.warn(`Skipping missing target: ${t}`);
    continue;
    }
    const tInfo = await analyzeTarget(target);
    const ti = await info(t);
    console.log(
    `\n📁 Target: ${target} (files: ${tInfo.totalFiles}, ts: ${tInfo.tsFiles}, js: ${tInfo.jsFiles})`,
    `\n📁 Target: ${t} (files: ${ti.totalFiles}, ts: ${ti.tsFiles}, js: ${ti.jsFiles})`,
    );
    if (verbose) {
    const resolvedPatterns =
    patterns && patterns.length > 0
    ? patterns
    : [path.join(target, '**', '*.ts')];
    const configPath = path.join(target, 'eslint.config.js');
    await printStylishOutputOnce(
    resolvedPatterns,
    (await pathExists(configPath)) ? configPath : undefined,
    );
    }

    for (const c of concurrency) {
    if (verbose) await stylish(t);
    for (const c of conc) {
    console.log(` 🔧 Concurrency: ${c}`);
    const runsData: BenchmarkRun[] = [];
    const rs: Run[] = [];
    for (let i = 1; i <= runs; i++) {
    console.log(` Run ${i}/${runs} ...`);
    const resolvedPatterns =
    patterns && patterns.length > 0
    ? patterns
    : [path.join(target, '**', '*.ts')];
    const configPath = path.join(target, 'eslint.config.js');
    const run = await runESLintOnce(
    target,
    c,
    i,
    verbose,
    resolvedPatterns,
    (await pathExists(configPath)) ? configPath : undefined,
    );
    runsData.push(run);
    const r = await once(t, c, i, verbose, useLocalConfig, tsOnly);
    rs.push(r);
    console.log(
    ` Time: ${run.timing.durationSeconds.toFixed(3)}s, Files: ${run.eslintResults.filesProcessed}, Errors: ${run.eslintResults.errors}, Warnings: ${run.eslintResults.warnings}${run.eslintResults.eslintWarnings.length ? ' ⚠️ ' + run.eslintResults.eslintWarnings.join(',') : ''}`,
    ` Time: ${r.timing.durationSeconds.toFixed(3)}s, Files: ${r.eslintResults.filesProcessed}, Errors: ${r.eslintResults.errors}, Warnings: ${r.eslintResults.warnings}${r.eslintResults.eslintWarnings.length ? ' ⚠️ ' + r.eslintResults.eslintWarnings.join(',') : ''}`,
    );
    }
    const stats = statsFrom(runsData.map(r => r.timing.durationSeconds));
    suiteResults.push({
    target,
    targetInfo: tInfo,
    const s = statz(rs.map(r => r.timing.durationSeconds));
    results.push({
    target: t,
    targetInfo: ti,
    concurrency: c,
    statistics: stats,
    runs: runsData,
    statistics: s,
    runs: rs,
    });
    console.log(
    ` ✅ Avg: ${stats.avg}s (min ${stats.min.toFixed(3)}s, max ${stats.max.toFixed(3)}s, ±${stats.stdDev}s)`,
    ` ✅ Avg: ${s.avg}s (min ${s.min.toFixed(3)}s, max ${s.max.toFixed(3)}s, ±${s.stdDev}s)`,
    );
    }
    }

    await writeFile(
    resultsPath,
    JSON.stringify({ systemInfo, results: suiteResults }, null, 2),
    resPath,
    JSON.stringify({ systemInfo: si, results }, null, 2),
    );

    // Write human-friendly summary
    const lines: string[] = [];
    lines.push('ESLint Concurrency Benchmark Summary');
    lines.push(`Generated: ${new Date().toString()}`);
    lines.push('');
    lines.push('System:');
    lines.push(`- OS: ${systemInfo.system.os} ${systemInfo.system.osVersion}`);
    lines.push(`- CPU Cores: ${systemInfo.system.cpuCores}`);
    lines.push(`- Memory: ${systemInfo.system.totalMemGb} GB`);
    lines.push(`- Node: ${systemInfo.software.nodeVersion}`);
    lines.push(`- ESLint: ${systemInfo.software.eslintVersion}`);
    if (systemInfo.software.nxVersion)
    lines.push(`- Nx: ${systemInfo.software.nxVersion}`);
    lines.push('');
    for (const group of suiteResults) {
    lines.push(
    `Target: ${group.target} (files: ${group.targetInfo.totalFiles}, ts: ${group.targetInfo.tsFiles}, js: ${group.targetInfo.jsFiles})`,
    );
    lines.push(
    ` Concurrency=${group.concurrency} → Avg=${group.statistics.avg}s (min=${group.statistics.min.toFixed(3)}s, max=${group.statistics.max.toFixed(3)}s, stdDev=${group.statistics.stdDev}s)`,
    );
    }
    await writeFile(summaryPath, lines.join('\n'));

    console.log('\n✅ Benchmark complete');
    console.log(`Raw results: ${resultsPath}`);
    console.log(`Summary: ${summaryPath}`);

    // Print fastest table to console
    const targetsSet = Array.from(new Set(suiteResults.map(r => r.target)));
    const tableRows: Array<{
    target: string;
    bestConc: Concurrency;
    bestAvg: number;
    baseline: number | null;
    speedup: string;
    }> = [];
    for (const t of targetsSet) {
    const byTarget = suiteResults.filter(r => r.target === t);
    if (byTarget.length === 0) continue;
    const best = byTarget.reduce((a, b) =>
    // Build Markdown summary (system info, fastest table, per-target breakdown)
    const tset = Array.from(new Set(results.map((r: any) => r.target)));
    const rows = tset.map(t => {
    const xs = results.filter((r: any) => r.target === t);
    const best = xs.reduce((a: any, b: any) =>
    a.statistics.avg <= b.statistics.avg ? a : b,
    );
    const baseline =
    byTarget.find(r => r.concurrency === 'off')?.statistics.avg ?? null;
    const speedupVal = baseline ? baseline / best.statistics.avg : null;
    tableRows.push({
    target: t,
    bestConc: best.concurrency,
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const speed = base ? (base / best.statistics.avg).toFixed(2) + 'x' : 'n/a';
    return {
    t,
    bestConc: best.concurrency as C,
    bestAvg: Number(best.statistics.avg.toFixed(3)),
    baseline,
    speedup: speedupVal ? `${speedupVal.toFixed(2)}x` : 'n/a',
    });
    base,
    speed,
    };
    });

    const md: string[] = [];
    md.push('# ESLint Concurrency Benchmark Report');
    md.push('');
    md.push(`Generated: ${new Date().toString()}`);
    md.push('');
    md.push('## System');
    md.push(`- **OS**: ${si.system.os} ${si.system.osVersion}`);
    md.push(`- **CPU Cores**: ${si.system.cpuCores}`);
    md.push(`- **Memory**: ${si.system.totalMemGb} GB`);
    md.push(`- **Node**: \\`${si.software.nodeVersion}\\``);
    md.push(`- **ESLint**: \\`${si.software.eslintVersion}\\``);
    if (si.software.nxVersion) md.push(`- **Nx**: \\`${si.software.nxVersion}\\``);
    md.push('');

    md.push('## Fastest per target');
    md.push('');
    md.push('| Target | Best | Avg (s) | Baseline (s) | Speedup |');
    md.push('|---|:---:|---:|---:|---:|');
    for (const r of rows) {
    md.push(`| \\`${r.t}\\` | **${r.bestConc}** | **${r.bestAvg.toFixed(3)}** | ${r.base ? r.base.toFixed(3) : 'n/a'} | **${r.speed}** |`);
    }
    md.push('');

    md.push('## Per-target breakdown');
    md.push('Best rows are marked with ★.');
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base = xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const bestAvg = Math.min(...xs.map((r: any) => r.statistics.avg));
    md.push('');
    md.push(`### \\`${t}\\``);
    md.push('');
    md.push('| Concurrency | Avg (s) | StdDev | Speedup |');
    md.push('|:-----------:|---:|---:|---:|');
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const isBest = Math.abs(r.statistics.avg - bestAvg) < 1e-6;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    const row = `| \\`${String(c)}\\` | ${r.statistics.avg.toFixed(3)} | ${r.statistics.stdDev.toFixed(3)} | ${sp} | ${isBest ? '' : ''}`;
    md.push(isBest ? row.replace(/\| ([^|]+) \|/, match => match.replace(/([^|]+)/, '**$1**')) : row);
    }
    }
    const pad = (s: string, n: number) =>
    s.length >= n ? s : s + ' '.repeat(n - s.length);

    await writeFile(sumPath, md.join('\n'));
    console.log('\n✅ Benchmark complete');
    console.log(`Raw results: ${resPath}`);
    console.log(`Summary: ${sumPath}`);
    // Reuse computed tset/rows for terminal tables
    const header = `${pad('Target', 28)} ${pad('Best', 6)} ${pad('Avg(s)', 8)} ${pad('Baseline(s)', 12)} Speedup`;
    console.log('\nFastest per target:');
    console.log(header);
    console.log('-'.repeat(header.length));
    for (const row of tableRows) {
    for (const r of rows)
    console.log(
    `${pad(row.target, 28)} ${pad(String(row.bestConc), 6)} ${pad(row.bestAvg.toFixed(3), 8)} ${pad(row.baseline ? row.baseline.toFixed(3) : 'n/a', 12)} ${row.speedup}`,
    `${pad(r.t, 28)} ${pad(String(r.bestConc), 6)} ${pad(r.bestAvg.toFixed(3), 8)} ${pad(r.base ? r.base.toFixed(3) : 'n/a', 12)} ${r.speed}`,
    );
    }

    // Per-target detailed table marking the best
    console.log('\nPer-target breakdown (best marked with ★):');
    for (const t of targetsSet) {
    const byTarget = suiteResults.filter(r => r.target === t);
    if (byTarget.length === 0) continue;
    const baseline =
    byTarget.find(r => r.concurrency === 'off')?.statistics.avg ?? null;
    const bestAvg = Math.min(...byTarget.map(r => r.statistics.avg));
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const best = Math.min(...xs.map((r: any) => r.statistics.avg));
    console.log(`\n${t}`);
    const h2 = `${pad('Concurrency', 12)} ${pad('Avg(s)', 8)} ${pad('StdDev', 8)} ${pad('Speedup', 8)} Mark`;
    console.log(h2);
    console.log('-'.repeat(h2.length));
    for (const c of new Set(byTarget.map(r => r.concurrency))) {
    const r = byTarget.find(x => x.concurrency === c);
    if (!r) continue;
    const isBest = Math.abs(r.statistics.avg - bestAvg) < 1e-6;
    const speed = baseline
    ? `${(baseline / r.statistics.avg).toFixed(2)}x`
    : 'n/a';
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    console.log(
    `${pad(String(c), 12)} ${pad(r.statistics.avg.toFixed(3), 8)} ${pad(r.statistics.stdDev.toFixed(3), 8)} ${pad(speed, 8)} ${isBest ? '' : ''}`,
    `${pad(String(c), 12)} ${pad(r.statistics.avg.toFixed(3), 8)} ${pad(r.statistics.stdDev.toFixed(3), 8)} ${pad(sp, 8)} ${Math.abs(r.statistics.avg - best) < 1e-6 ? '' : ''}`,
    );
    }
    }
    }

    main().catch(err => {
    console.error(err);
    main().catch(e => {
    console.error(e);
    process.exitCode = 1;
    });

  2. BioPhoton revised this gist Aug 23, 2025. 1 changed file with 14 additions and 15 deletions.
    29 changes: 14 additions & 15 deletions ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # ESLint Concurrency Benchmark Script
    # ESLint Concurrency Benchmark (compact)

    ## Overview
    - Benchmarks ESLint v9.34+ `--concurrency` across one or more targets
    @@ -9,18 +9,19 @@
    ## Defaults
    - **concurrency**: `off,4,8,auto`
    - **runs**: `3`
    - **useLocalConfig**: `true` (uses `<target>/eslint.config.js`)
    - **tsOnly**: `true` (globs TS files under `<target>` recursively)
    - **outDir**: `tools/eslint-perf/results`

    > Note:
    > - `bench.compact.ts` defaults: uses `<target>/eslint.config.js` if present and lints TypeScript files under `<target>`.
    > - `bench.ts` supports custom patterns via `--patterns` and will default to `<target>/**/*.ts` and auto-use `<target>/eslint.config.js` if present when `--patterns` is not provided.
    ## Flags
    - `--targets=dir[,dir...]`: Comma-separated target directories
    - `--concurrency=v[,v...]`: values in `{off,auto,1..N}`
    - `--runs=N`: Runs per configuration (default `3`)
    - `--verbose`: Show ESLint commands/stderr and one stylish preview per target
    - `--useLocalConfig=true|false`: Pass `--config <target>/eslint.config.js` (default `true`)
    - `--tsOnly=true|false`: Limit to TS files under `<target>` recursively (default `true`)
    - `--outDir=path`: Directory for JSON + summary outputs
    - `--patterns=glob[,glob...]`: (bench.ts) Explicit file globs to lint (e.g. `packages/utils/**/*.ts,packages/utils/**/*.tsx`)

    ## Examples
    - Minimal (defaults):
    @@ -36,10 +37,12 @@ node --import tsx tools/eslint-perf/bench.compact.ts \
    --runs=5
    ```

    - Disable local config or TS-only:
    - Custom patterns (bench.ts):
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts \
    --useLocalConfig=false --tsOnly=false
    node --import tsx tools/eslint-perf/bench.ts \
    --targets=packages/lib-a \
    --patterns="packages/lib-a/**/*.ts,packages/lib-a/**/*.tsx" \
    --concurrency=off,4,auto
    ```

    ## Output
    @@ -49,8 +52,7 @@ node --import tsx tools/eslint-perf/bench.compact.ts \

    ### Output Example
    ```bash
    > node --import tsx bench.ts --targets=packages/lib-a --concurrency=off,1,2,4,6,8,auto --runs=3 --verbose --useLocalConfig --tsOnly

    > node --import tsx tools/eslint-perf/bench.ts --targets=packages/lib-a --concurrency=off,1,2,4,6,8,auto --runs=3 --verbose

    📁 Target: packages/lib-a (files: 106, ts: 101, js: 5)
    🔧 Concurrency: off
    @@ -63,7 +65,7 @@ node --import tsx tools/eslint-perf/bench.compact.ts \

    ✅ Benchmark complete
    Raw results: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.json
    Summary: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.summary.txt
    Summary: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.summary.md

    Fastest per target:
    Target Best Avg(s) Baseline(s) Speedup
    @@ -82,14 +84,11 @@ off 8.849 0.078 1.00x ★
    6 11.652 0.439 0.76x
    8 13.749 0.195 0.64x
    auto 9.490 0.095 0.93x

    ```


    # CPU Measures

    ```bash
    npx @push-based/cpu-prof@latest npx eslint . --concurrency=4
    npx @push-based/cpu-prof@latest npx eslint . --concurrency=4
    ```


  3. BioPhoton revised this gist Aug 23, 2025. 1 changed file with 396 additions and 238 deletions.
    634 changes: 396 additions & 238 deletions ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -94,6 +94,11 @@ npx @push-based/cpu-prof@latest npx eslint . --concurrency=4


    ```ts
    /*
    * ESLint Concurrency Benchmark Suite
    * Runs ESLint with multiple concurrency settings across selected targets,
    * collects timings and quantitative data, and writes structured results.
    */
    import { exec as execCb } from 'node:child_process';
    import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';
    import os from 'node:os';
    @@ -102,16 +107,17 @@ import { promisify } from 'node:util';

    const exec = promisify(execCb);

    type C = 'off' | 'auto' | `${number}`;
    type Run = {
    type Concurrency = 'off' | 'auto' | `${number}`;

    type BenchmarkRun = {
    target: string;
    concurrency: C;
    concurrency: Concurrency;
    run: number;
    timing: {
    durationSeconds: number;
    realTimeSeconds: null;
    userTimeSeconds: null;
    sysTimeSeconds: null;
    realTimeSeconds: number | null;
    userTimeSeconds: number | null;
    sysTimeSeconds: number | null;
    };
    eslintResults: {
    filesProcessed: number;
    @@ -121,194 +127,295 @@ type Run = {
    };
    timestamp: string;
    };
    type Stats = {
    runs: number;

    type BenchmarkStats = {
    avg: number;
    min: number;
    max: number;
    avg: number;
    stdDev: number;
    runs: number;
    };
    type TI = {

    type TargetInfo = {
    target: string;
    tsFiles: number;
    jsFiles: number;
    totalFiles: number;
    };

    const DFLT_TARGETS = [
    type SuiteResult = {
    target: string;
    targetInfo: TargetInfo;
    concurrency: Concurrency;
    statistics: BenchmarkStats;
    runs: BenchmarkRun[];
    };

    type SystemInfo = {
    timestamp: string;
    system: {
    os: string;
    osVersion: string;
    architecture: string;
    cpuCores: number;
    totalMemGb: number;
    hostname: string;
    };
    software: {
    nodeVersion: string;
    npmVersion: string;
    eslintVersion: string;
    nxVersion: string | null;
    };
    };

    // -----------------------------
    // Config via CLI args (minimal)
    // -----------------------------
    const DEFAULT_TARGETS = [
    'packages/models',
    'packages/plugin-eslint',
    'packages/cli',
    'packages/core',
    'packages/utils',
    ];
    const DFLT_CONC: C[] = ['off', '4', '8', 'auto'];
    const DFLT_RUNS = 3;
    const pad = (s: string, n: number) =>
    s.length >= n ? s : s + ' '.repeat(n - s.length);
    const exists = async (p: string) => !!(await stat(p).catch(() => null));
    const ensureDir = (d: string) => mkdir(d, { recursive: true });

    function args() {
    const a = process.argv.slice(2);
    const get = (n: string) =>
    a.find(x => x.startsWith(`--${n}=`))?.split('=')[1];
    const targets = get('targets')?.split(',').filter(Boolean) ?? DFLT_TARGETS;
    const conc =
    (get('concurrency')?.split(',').filter(Boolean) as C[] | undefined) ??
    DFLT_CONC;
    const runs = Number.parseInt(get('runs') ?? `${DFLT_RUNS}`, 10);
    const outDir = get('outDir') ?? path.join('tools', 'eslint-perf', 'results');
    const verbose = a.includes('--verbose') || get('verbose') === 'true';
    const useLocalConfig = get('useLocalConfig') === 'false' ? false : true;
    const tsOnly = get('tsOnly') === 'false' ? false : true;
    return { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly };
    const DEFAULT_CONCURRENCY: Concurrency[] = [
    'off',
    '1',
    '2',
    '4',
    '6',
    '8',
    'auto',
    ];
    const DEFAULT_RUNS = 3;

    function parseArgs() {
    const args = process.argv.slice(2);
    const getArg = (name: string): string | undefined => {
    const prefix = `--${name}=`;
    return args.find(a => a.startsWith(prefix))?.slice(prefix.length);
    };

    const targets =
    getArg('targets')?.split(',').filter(Boolean) ?? DEFAULT_TARGETS;
    const conc = getArg('concurrency')?.split(',').filter(Boolean) as
    | Concurrency[]
    | undefined;
    const concurrency = conc && conc.length > 0 ? conc : DEFAULT_CONCURRENCY;
    const runs = Number.parseInt(getArg('runs') ?? `${DEFAULT_RUNS}`, 10);
    const outDir =
    getArg('outDir') ?? path.join('tools', 'eslint-perf', 'results');

    const verbose = args.includes('--verbose') || getArg('verbose') === 'true';
    const patterns = getArg('patterns')
    ?.split(',')
    .map(p => p.trim())
    .filter(Boolean);

    return {
    targets,
    concurrency,
    runs,
    outDir,
    verbose,
    patterns,
    };
    }

    // -----------------------------
    // Utilities
    // -----------------------------
    async function pathExists(p: string): Promise<boolean> {
    try {
    await stat(p);
    return true;
    } catch {
    return false;
    }
    }

    async function sys() {
    const nx = await exec('npx nx --version')
    .then(r => r.stdout.trim().split('\n')[0])
    .catch(() => null);
    async function collectSystemInfo(): Promise<SystemInfo> {
    const cpuCores = os.cpus()?.length ?? 0;
    const totalMemGb = Math.round((os.totalmem() / 1024 ** 3) * 100) / 100;
    const nodeVersion = process.version;
    const npmVersion = (await exec('npm --version')).stdout.trim();
    const eslintVersion = (await exec('npx eslint --version')).stdout.trim();
    let nxVersion: string | null = null;
    try {
    nxVersion =
    (await exec('npx nx --version')).stdout.trim().split('\n')[0] ?? null;
    } catch {
    nxVersion = null;
    }

    return {
    timestamp: new Date().toISOString(),
    system: {
    os: os.platform(),
    osVersion: os.release(),
    architecture: os.arch(),
    cpuCores: os.cpus()?.length ?? 0,
    totalMemGb: Math.round((os.totalmem() / 1024 ** 3) * 100) / 100,
    cpuCores,
    totalMemGb,
    hostname: os.hostname(),
    },
    software: {
    nodeVersion: process.version,
    npmVersion: (await exec('npm --version')).stdout.trim(),
    eslintVersion: (await exec('npx eslint --version')).stdout.trim(),
    nxVersion: nx,
    nodeVersion,
    npmVersion,
    eslintVersion,
    nxVersion,
    },
    };
    }

    async function count(dir: string, exts: string[]) {
    let n = 0;
    const w = async (d: string): Promise<void> => {
    const es = await readdir(d, { withFileTypes: true });
    for (const e of es) {
    const p = path.join(d, e.name);
    if (e.isDirectory()) {
    if (['node_modules', 'dist', 'coverage'].includes(e.name)) continue;
    await w(p);
    } else if (e.isFile() && exts.some(ext => e.name.endsWith(ext))) n++;
    async function walkCountFiles(
    dir: string,
    extensions: string[],
    ): Promise<number> {
    let count = 0;
    async function walk(current: string): Promise<void> {
    const entries = await readdir(current, { withFileTypes: true });
    for (const entry of entries) {
    const p = path.join(current, entry.name);
    if (entry.isDirectory()) {
    if (
    entry.name === 'node_modules' ||
    entry.name === 'dist' ||
    entry.name === 'coverage'
    )
    continue;
    await walk(p);
    } else if (entry.isFile()) {
    if (extensions.some(ext => entry.name.endsWith(ext))) count += 1;
    }
    }
    }
    await walk(dir);
    return count;
    }

    async function analyzeTarget(target: string): Promise<TargetInfo> {
    const abs = path.resolve(target);
    const tsFiles = (await pathExists(abs))
    ? await walkCountFiles(abs, ['.ts', '.tsx'])
    : 0;
    const jsFiles = (await pathExists(abs))
    ? await walkCountFiles(abs, ['.js', '.jsx', '.mjs', '.cjs'])
    : 0;
    return {
    target,
    tsFiles,
    jsFiles,
    totalFiles: tsFiles + jsFiles,
    };
    await w(dir);
    return n;
    }
    async function info(t: string): Promise<TE> {
    const abs = path.resolve(t);
    if (!(await exists(abs)))
    return { target: t, tsFiles: 0, jsFiles: 0, totalFiles: 0 };
    const ts = await count(abs, ['.ts', '.tsx']);
    const js = await count(abs, ['.js', '.jsx', '.mjs', '.cjs']);
    return { target: t, tsFiles: ts, jsFiles: js, totalFiles: ts + js };

    function buildEslintCommand(
    concurrency: Concurrency,
    options: { patterns: string[]; json: boolean; configPath?: string },
    ): string {
    const configArg = options.configPath
    ? ` --config=${JSON.stringify(options.configPath)}`
    : '';
    const patternArgs = options.patterns.map(p => JSON.stringify(p)).join(' ');
    const formatArg = options.json ? '--format=json' : '--format=stylish';
    return `npx eslint${configArg} --concurrency=${concurrency} ${formatArg} ${patternArgs}`;
    }
    type TE = TI;

    const cmd = (
    t: string,
    c: C,
    o: { local: boolean; ts: boolean; json: boolean },
    ) =>
    `npx eslint${o.local ? ` --config=${JSON.stringify(path.join(t, 'eslint.config.js'))}` : ''} --concurrency=${c} ${o.json ? '--format=json' : '--format=stylish'} ${[o.ts ? path.join(t, '**', '*.ts') : t].map(p => JSON.stringify(p)).join(' ')}`;

    async function once(
    t: string,
    c: C,
    i: number,
    v: boolean,
    local: boolean,
    ts: boolean,
    ): Promise<Run> {
    const s = process.hrtime.bigint();
    const k = cmd(t, c, { local, ts, json: true });
    let out = '',
    err = '';

    async function runESLintOnce(
    target: string,
    concurrency: Concurrency,
    run: number,
    verbose = false,
    patterns: string[],
    configPath?: string,
    ): Promise<BenchmarkRun> {
    const start = process.hrtime.bigint();
    const cmd = buildEslintCommand(concurrency, {
    patterns,
    json: true,
    configPath,
    });
    let stdout = '';
    let stderr = '';
    try {
    const r = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    out = r.stdout;
    err = r.stderr;
    const result = await exec(cmd, { maxBuffer: 1024 * 1024 * 200 });
    stdout = result.stdout;
    stderr = result.stderr;
    } catch (e: any) {
    out = e.stdout ?? '';
    err = e.stderr ?? '';
    stdout = e.stdout ?? '';
    stderr = e.stderr ?? '';
    }
    if (v) {
    console.log(` $ ${k}`);
    if (err.trim()) {
    if (verbose) {
    console.log(` $ ${cmd}`);
    if (stderr.trim()) {
    console.log(' [stderr]');
    console.log(
    err
    stderr
    .split('\n')
    .map(l => ` ${l}`)
    .join('\n'),
    );
    }
    }
    const d = Number(process.hrtime.bigint() - s) / 1_000_000_000;
    let files = 0,
    errors = 0,
    warnings = 0;
    const end = process.hrtime.bigint();
    const durationSeconds = Number(end - start) / 1_000_000_000;

    // Parse JSON output
    let filesProcessed = 0;
    let errors = 0;
    let warnings = 0;
    try {
    const j = JSON.parse(out) as Array<{
    const json = JSON.parse(stdout) as Array<{
    errorCount: number;
    warningCount: number;
    }>;
    files = j.length;
    for (const r of j) {
    filesProcessed = json.length;
    for (const r of json) {
    errors += r.errorCount || 0;
    warnings += r.warningCount || 0;
    }
    } catch {}
    const warns = err.includes('ESLintPoorConcurrencyWarning')
    ? ['ESLintPoorConcurrencyWarning']
    : [];
    } catch {
    // ignore parse errors
    }

    const eslintWarnings: string[] = [];
    if (stderr.includes('ESLintPoorConcurrencyWarning'))
    eslintWarnings.push('ESLintPoorConcurrencyWarning');

    return {
    target: t,
    concurrency: c,
    run: i,
    target,
    concurrency,
    run,
    timing: {
    durationSeconds: d,
    durationSeconds,
    realTimeSeconds: null,
    userTimeSeconds: null,
    sysTimeSeconds: null,
    },
    eslintResults: {
    filesProcessed: files,
    filesProcessed,
    errors,
    warnings,
    eslintWarnings: warns,
    eslintWarnings,
    },
    timestamp: new Date().toISOString(),
    };
    }

    const statz = (xs: number[]): Stats => {
    const n = xs.length,
    min = Math.min(...xs),
    max = Math.max(...xs),
    avg = xs.reduce((a, b) => a + b, 0) / n,
    sd = Math.sqrt(xs.reduce((a, v) => a + (v - avg) ** 2, 0) / n);
    return {
    runs: n,
    min,
    max,
    avg: Number(avg.toFixed(3)),
    stdDev: Number(sd.toFixed(3)),
    };
    };

    async function stylish(t: string) {
    const k = cmd(t, 'off', { local: true, ts: true, json: false });
    async function printStylishOutputOnce(
    patterns: string[],
    configPath?: string,
    ): Promise<void> {
    const cmdStylish = buildEslintCommand('off', {
    patterns,
    json: false,
    configPath,
    });
    try {
    const { stdout, stderr } = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    const { stdout, stderr } = await exec(cmdStylish, {
    maxBuffer: 1024 * 1024 * 200,
    });
    if (stdout.trim()) {
    console.log(' [stylish output]');
    console.log(
    @@ -329,22 +436,22 @@ async function stylish(t: string) {
    );
    }
    } catch (e: any) {
    const o = e.stdout ?? '',
    er = e.stderr ?? '';
    if (o.trim()) {
    const out = e.stdout ?? '';
    const err = e.stderr ?? '';
    if (out.trim()) {
    console.log(' [stylish output]');
    console.log(
    o
    out
    .split('\n')
    .slice(0, 300)
    .map((l: string) => ` ${l}`)
    .join('\n'),
    );
    }
    if (er.trim()) {
    if (err.trim()) {
    console.log(' [stylish stderr]');
    console.log(
    er
    err
    .split('\n')
    .map((l: string) => ` ${l}`)
    .join('\n'),
    @@ -353,155 +460,206 @@ async function stylish(t: string) {
    }
    }

    async function main() {
    const { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly } =
    args();
    function statsFrom(values: number[]): BenchmarkStats {
    const runs = values.length;
    const min = Math.min(...values);
    const max = Math.max(...values);
    const avg = values.reduce((a, b) => a + b, 0) / runs;
    const variance = values.reduce((acc, v) => acc + (v - avg) ** 2, 0) / runs;
    const stdDev = Math.sqrt(variance);
    return {
    runs,
    min,
    max,
    avg: Number(avg.toFixed(3)),
    stdDev: Number(stdDev.toFixed(3)),
    };
    }

    async function ensureDir(dir: string): Promise<void> {
    await mkdir(dir, { recursive: true });
    }

    async function main(): Promise<void> {
    const { targets, concurrency, runs, outDir, verbose, patterns } = parseArgs();
    await ensureDir(outDir);

    const systemInfo = await collectSystemInfo();
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const resultsPath = path.join(outDir, `eslint-benchmark-${timestamp}.json`);
    const summaryPath = path.join(
    outDir,
    `eslint-benchmark-${timestamp}.summary.txt`,
    );

    const suiteResults: SuiteResult[] = [];

    // Write system info immediately
    await ensureDir(outDir);
    const si = await sys(),
    ts = new Date().toISOString().replace(/[:.]/g, '-');
    const resPath = path.join(outDir, `eslint-benchmark-${ts}.json`),
    sumPath = path.join(outDir, `eslint-benchmark-${ts}.summary.md`);
    const results: any[] = [];
    await writeFile(
    path.join(outDir, `system-info-${ts}.json`),
    JSON.stringify(si, null, 2),
    path.join(outDir, `system-info-${timestamp}.json`),
    JSON.stringify(systemInfo, null, 2),
    );
    for (const t of targets) {
    if (!(await exists(path.resolve(t)))) {
    console.warn(`Skipping missing target: ${t}`);

    for (const target of targets) {
    const absTarget = path.resolve(target);
    if (!(await pathExists(absTarget))) {
    console.warn(`Skipping missing target: ${target}`);
    continue;
    }
    const ti = await info(t);
    const tInfo = await analyzeTarget(target);
    console.log(
    `\n📁 Target: ${t} (files: ${ti.totalFiles}, ts: ${ti.tsFiles}, js: ${ti.jsFiles})`,
    `\n📁 Target: ${target} (files: ${tInfo.totalFiles}, ts: ${tInfo.tsFiles}, js: ${tInfo.jsFiles})`,
    );
    if (verbose) await stylish(t);
    for (const c of conc) {
    if (verbose) {
    const resolvedPatterns =
    patterns && patterns.length > 0
    ? patterns
    : [path.join(target, '**', '*.ts')];
    const configPath = path.join(target, 'eslint.config.js');
    await printStylishOutputOnce(
    resolvedPatterns,
    (await pathExists(configPath)) ? configPath : undefined,
    );
    }

    for (const c of concurrency) {
    console.log(` 🔧 Concurrency: ${c}`);
    const rs: Run[] = [];
    const runsData: BenchmarkRun[] = [];
    for (let i = 1; i <= runs; i++) {
    console.log(` Run ${i}/${runs} ...`);
    const r = await once(t, c, i, verbose, useLocalConfig, tsOnly);
    rs.push(r);
    const resolvedPatterns =
    patterns && patterns.length > 0
    ? patterns
    : [path.join(target, '**', '*.ts')];
    const configPath = path.join(target, 'eslint.config.js');
    const run = await runESLintOnce(
    target,
    c,
    i,
    verbose,
    resolvedPatterns,
    (await pathExists(configPath)) ? configPath : undefined,
    );
    runsData.push(run);
    console.log(
    ` Time: ${r.timing.durationSeconds.toFixed(3)}s, Files: ${r.eslintResults.filesProcessed}, Errors: ${r.eslintResults.errors}, Warnings: ${r.eslintResults.warnings}${r.eslintResults.eslintWarnings.length ? ' ⚠️ ' + r.eslintResults.eslintWarnings.join(',') : ''}`,
    ` Time: ${run.timing.durationSeconds.toFixed(3)}s, Files: ${run.eslintResults.filesProcessed}, Errors: ${run.eslintResults.errors}, Warnings: ${run.eslintResults.warnings}${run.eslintResults.eslintWarnings.length ? ' ⚠️ ' + run.eslintResults.eslintWarnings.join(',') : ''}`,
    );
    }
    const s = statz(rs.map(r => r.timing.durationSeconds));
    results.push({
    target: t,
    targetInfo: ti,
    const stats = statsFrom(runsData.map(r => r.timing.durationSeconds));
    suiteResults.push({
    target,
    targetInfo: tInfo,
    concurrency: c,
    statistics: s,
    runs: rs,
    statistics: stats,
    runs: runsData,
    });
    console.log(
    ` ✅ Avg: ${s.avg}s (min ${s.min.toFixed(3)}s, max ${s.max.toFixed(3)}s, ±${s.stdDev}s)`,
    ` ✅ Avg: ${stats.avg}s (min ${stats.min.toFixed(3)}s, max ${stats.max.toFixed(3)}s, ±${stats.stdDev}s)`,
    );
    }
    }

    await writeFile(
    resPath,
    JSON.stringify({ systemInfo: si, results }, null, 2),
    resultsPath,
    JSON.stringify({ systemInfo, results: suiteResults }, null, 2),
    );

    // Build Markdown summary (system info, fastest table, per-target breakdown)
    const tset = Array.from(new Set(results.map((r: any) => r.target)));
    const rows = tset.map(t => {
    const xs = results.filter((r: any) => r.target === t);
    const best = xs.reduce((a: any, b: any) =>
    a.statistics.avg <= b.statistics.avg ? a : b,
    // Write human-friendly summary
    const lines: string[] = [];
    lines.push('ESLint Concurrency Benchmark Summary');
    lines.push(`Generated: ${new Date().toString()}`);
    lines.push('');
    lines.push('System:');
    lines.push(`- OS: ${systemInfo.system.os} ${systemInfo.system.osVersion}`);
    lines.push(`- CPU Cores: ${systemInfo.system.cpuCores}`);
    lines.push(`- Memory: ${systemInfo.system.totalMemGb} GB`);
    lines.push(`- Node: ${systemInfo.software.nodeVersion}`);
    lines.push(`- ESLint: ${systemInfo.software.eslintVersion}`);
    if (systemInfo.software.nxVersion)
    lines.push(`- Nx: ${systemInfo.software.nxVersion}`);
    lines.push('');
    for (const group of suiteResults) {
    lines.push(
    `Target: ${group.target} (files: ${group.targetInfo.totalFiles}, ts: ${group.targetInfo.tsFiles}, js: ${group.targetInfo.jsFiles})`,
    );
    lines.push(
    ` Concurrency=${group.concurrency} → Avg=${group.statistics.avg}s (min=${group.statistics.min.toFixed(3)}s, max=${group.statistics.max.toFixed(3)}s, stdDev=${group.statistics.stdDev}s)`,
    );
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const speed = base ? (base / best.statistics.avg).toFixed(2) + 'x' : 'n/a';
    return {
    t,
    bestConc: best.concurrency as C,
    bestAvg: Number(best.statistics.avg.toFixed(3)),
    base,
    speed,
    };
    });

    const md: string[] = [];
    md.push('# ESLint Concurrency Benchmark Report');
    md.push('');
    md.push(`Generated: ${new Date().toString()}`);
    md.push('');
    md.push('## System');
    md.push(`- **OS**: ${si.system.os} ${si.system.osVersion}`);
    md.push(`- **CPU Cores**: ${si.system.cpuCores}`);
    md.push(`- **Memory**: ${si.system.totalMemGb} GB`);
    md.push(`- **Node**: \\`${si.software.nodeVersion}\\``);
    md.push(`- **ESLint**: \\`${si.software.eslintVersion}\\``);
    if (si.software.nxVersion) md.push(`- **Nx**: \\`${si.software.nxVersion}\\``);
    md.push('');

    md.push('## Fastest per target');
    md.push('');
    md.push('| Target | Best | Avg (s) | Baseline (s) | Speedup |');
    md.push('|---|:---:|---:|---:|---:|');
    for (const r of rows) {
    md.push(`| \\`${r.t}\\` | **${r.bestConc}** | **${r.bestAvg.toFixed(3)}** | ${r.base ? r.base.toFixed(3) : 'n/a'} | **${r.speed}** |`);
    }
    md.push('');

    md.push('## Per-target breakdown');
    md.push('Best rows are marked with ★.');
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base = xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const bestAvg = Math.min(...xs.map((r: any) => r.statistics.avg));
    md.push('');
    md.push(`### \\`${t}\\``);
    md.push('');
    md.push('| Concurrency | Avg (s) | StdDev | Speedup |');
    md.push('|:-----------:|---:|---:|---:|');
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const isBest = Math.abs(r.statistics.avg - bestAvg) < 1e-6;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    const row = `| \\`${String(c)}\\` | ${r.statistics.avg.toFixed(3)} | ${r.statistics.stdDev.toFixed(3)} | ${sp} | ${isBest ? '' : ''}`;
    md.push(isBest ? row.replace(/\| ([^|]+) \|/, match => match.replace(/([^|]+)/, '**$1**')) : row);
    }
    }
    await writeFile(summaryPath, lines.join('\n'));

    await writeFile(sumPath, md.join('\n'));
    console.log('\n✅ Benchmark complete');
    console.log(`Raw results: ${resPath}`);
    console.log(`Summary: ${sumPath}`);
    // Reuse computed tset/rows for terminal tables
    console.log(`Raw results: ${resultsPath}`);
    console.log(`Summary: ${summaryPath}`);

    // Print fastest table to console
    const targetsSet = Array.from(new Set(suiteResults.map(r => r.target)));
    const tableRows: Array<{
    target: string;
    bestConc: Concurrency;
    bestAvg: number;
    baseline: number | null;
    speedup: string;
    }> = [];
    for (const t of targetsSet) {
    const byTarget = suiteResults.filter(r => r.target === t);
    if (byTarget.length === 0) continue;
    const best = byTarget.reduce((a, b) =>
    a.statistics.avg <= b.statistics.avg ? a : b,
    );
    const baseline =
    byTarget.find(r => r.concurrency === 'off')?.statistics.avg ?? null;
    const speedupVal = baseline ? baseline / best.statistics.avg : null;
    tableRows.push({
    target: t,
    bestConc: best.concurrency,
    bestAvg: Number(best.statistics.avg.toFixed(3)),
    baseline,
    speedup: speedupVal ? `${speedupVal.toFixed(2)}x` : 'n/a',
    });
    }
    const pad = (s: string, n: number) =>
    s.length >= n ? s : s + ' '.repeat(n - s.length);
    const header = `${pad('Target', 28)} ${pad('Best', 6)} ${pad('Avg(s)', 8)} ${pad('Baseline(s)', 12)} Speedup`;
    console.log('\nFastest per target:');
    console.log(header);
    console.log('-'.repeat(header.length));
    for (const r of rows)
    for (const row of tableRows) {
    console.log(
    `${pad(r.t, 28)} ${pad(String(r.bestConc), 6)} ${pad(r.bestAvg.toFixed(3), 8)} ${pad(r.base ? r.base.toFixed(3) : 'n/a', 12)} ${r.speed}`,
    `${pad(row.target, 28)} ${pad(String(row.bestConc), 6)} ${pad(row.bestAvg.toFixed(3), 8)} ${pad(row.baseline ? row.baseline.toFixed(3) : 'n/a', 12)} ${row.speedup}`,
    );
    }

    // Per-target detailed table marking the best
    console.log('\nPer-target breakdown (best marked with ★):');
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const best = Math.min(...xs.map((r: any) => r.statistics.avg));
    for (const t of targetsSet) {
    const byTarget = suiteResults.filter(r => r.target === t);
    if (byTarget.length === 0) continue;
    const baseline =
    byTarget.find(r => r.concurrency === 'off')?.statistics.avg ?? null;
    const bestAvg = Math.min(...byTarget.map(r => r.statistics.avg));
    console.log(`\n${t}`);
    const h2 = `${pad('Concurrency', 12)} ${pad('Avg(s)', 8)} ${pad('StdDev', 8)} ${pad('Speedup', 8)} Mark`;
    console.log(h2);
    console.log('-'.repeat(h2.length));
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    for (const c of new Set(byTarget.map(r => r.concurrency))) {
    const r = byTarget.find(x => x.concurrency === c);
    if (!r) continue;
    const isBest = Math.abs(r.statistics.avg - bestAvg) < 1e-6;
    const speed = baseline
    ? `${(baseline / r.statistics.avg).toFixed(2)}x`
    : 'n/a';
    console.log(
    `${pad(String(c), 12)} ${pad(r.statistics.avg.toFixed(3), 8)} ${pad(r.statistics.stdDev.toFixed(3), 8)} ${pad(sp, 8)} ${Math.abs(r.statistics.avg - best) < 1e-6 ? '' : ''}`,
    `${pad(String(c), 12)} ${pad(r.statistics.avg.toFixed(3), 8)} ${pad(r.statistics.stdDev.toFixed(3), 8)} ${pad(speed, 8)} ${isBest ? '' : ''}`,
    );
    }
    }
    }

    main().catch(e => {
    console.error(e);
    main().catch(err => {
    console.error(err);
    process.exitCode = 1;
    });

    ```
  4. BioPhoton revised this gist Aug 23, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # ESLint Concurrency Benchmark (compact)
    # ESLint Concurrency Benchmark Script

    ## Overview
    - Benchmarks ESLint v9.34+ `--concurrency` across one or more targets
  5. BioPhoton revised this gist Aug 23, 2025. 1 changed file with 48 additions and 2 deletions.
    50 changes: 48 additions & 2 deletions ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # ESLint Concurrency Benchmark Script
    # ESLint Concurrency Benchmark (compact)

    ## Overview
    - Benchmarks ESLint v9.34+ `--concurrency` across one or more targets
    @@ -31,7 +31,7 @@ node --import tsx tools/eslint-perf/bench.compact.ts
    - Custom targets + concurrency:
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts \
    --targets=packages/models,packages/utils \
    --targets=packages/lib-a,packages/lib-b \
    --concurrency=off,2,4,auto \
    --runs=5
    ```
    @@ -47,6 +47,52 @@ node --import tsx tools/eslint-perf/bench.compact.ts \
    - **Summary**: `tools/eslint-perf/results/*.summary.md`
    - **Terminal**: fastest table + per-target breakdown (★ marks best)

    ### Output Example
    ```bash
    > node --import tsx bench.ts --targets=packages/lib-a --concurrency=off,1,2,4,6,8,auto --runs=3 --verbose --useLocalConfig --tsOnly


    📁 Target: packages/lib-a (files: 106, ts: 101, js: 5)
    🔧 Concurrency: off
    Run 1/3 ...
    $ npx eslint --config="packages/lib-a/eslint.config.js" --concurrency=off --format=json "packages/lib-a/**/*.ts"
    Time: 8.764s, Files: 101, Errors: 0, Warnings: 0
    Run 2/3 ...
    ✅ Avg: 9.49s (min 9.385s, max 9.615s, ±0.095s)
    ...

    ✅ Benchmark complete
    Raw results: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.json
    Summary: tools/eslint-perf/results/eslint-benchmark-2025-08-23T01-39-46-558Z.summary.txt

    Fastest per target:
    Target Best Avg(s) Baseline(s) Speedup
    ---------------------------------------------------------------------
    packages/lib-a off 8.849 8.849 1.00x

    Per-target breakdown (best marked with ★):

    packages/lib-a
    Concurrency Avg(s) StdDev Speedup Mark
    ------------------------------------------------
    off 8.849 0.078 1.00x ★
    1 9.024 0.094 0.98x
    2 9.615 0.107 0.92x
    4 9.742 0.190 0.91x
    6 11.652 0.439 0.76x
    8 13.749 0.195 0.64x
    auto 9.490 0.095 0.93x

    ```


    # CPU Measures

    ```bash
    npx @push-based/cpu-prof@latest npx eslint . --concurrency=4
    ```


    ```ts
    import { exec as execCb } from 'node:child_process';
    import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';
  6. BioPhoton created this gist Aug 23, 2025.
    461 changes: 461 additions & 0 deletions ESLint--v9.34-Concurrency--Benchmarks.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,461 @@
    # ESLint Concurrency Benchmark Script

    ## Overview
    - Benchmarks ESLint v9.34+ `--concurrency` across one or more targets
    - Runs each concurrency setting multiple times and aggregates stats
    - Prints a fastest-per-target table and a per-target breakdown (★ marks best)
    - Optional verbose mode prints ESLint commands, stderr, and one stylish preview

    ## Defaults
    - **concurrency**: `off,4,8,auto`
    - **runs**: `3`
    - **useLocalConfig**: `true` (uses `<target>/eslint.config.js`)
    - **tsOnly**: `true` (globs TS files under `<target>` recursively)
    - **outDir**: `tools/eslint-perf/results`

    ## Flags
    - `--targets=dir[,dir...]`: Comma-separated target directories
    - `--concurrency=v[,v...]`: values in `{off,auto,1..N}`
    - `--runs=N`: Runs per configuration (default `3`)
    - `--verbose`: Show ESLint commands/stderr and one stylish preview per target
    - `--useLocalConfig=true|false`: Pass `--config <target>/eslint.config.js` (default `true`)
    - `--tsOnly=true|false`: Limit to TS files under `<target>` recursively (default `true`)
    - `--outDir=path`: Directory for JSON + summary outputs

    ## Examples
    - Minimal (defaults):
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts
    ```

    - Custom targets + concurrency:
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts \
    --targets=packages/models,packages/utils \
    --concurrency=off,2,4,auto \
    --runs=5
    ```

    - Disable local config or TS-only:
    ```bash
    node --import tsx tools/eslint-perf/bench.compact.ts \
    --useLocalConfig=false --tsOnly=false
    ```

    ## Output
    - **Raw JSON**: `tools/eslint-perf/results/system-info-*.json` and `eslint-benchmark-*.json`
    - **Summary**: `tools/eslint-perf/results/*.summary.md`
    - **Terminal**: fastest table + per-target breakdown (★ marks best)

    ```ts
    import { exec as execCb } from 'node:child_process';
    import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';
    import os from 'node:os';
    import path from 'node:path';
    import { promisify } from 'node:util';

    const exec = promisify(execCb);

    type C = 'off' | 'auto' | `${number}`;
    type Run = {
    target: string;
    concurrency: C;
    run: number;
    timing: {
    durationSeconds: number;
    realTimeSeconds: null;
    userTimeSeconds: null;
    sysTimeSeconds: null;
    };
    eslintResults: {
    filesProcessed: number;
    errors: number;
    warnings: number;
    eslintWarnings: string[];
    };
    timestamp: string;
    };
    type Stats = {
    runs: number;
    min: number;
    max: number;
    avg: number;
    stdDev: number;
    };
    type TI = {
    target: string;
    tsFiles: number;
    jsFiles: number;
    totalFiles: number;
    };

    const DFLT_TARGETS = [
    'packages/models',
    'packages/plugin-eslint',
    'packages/cli',
    'packages/core',
    'packages/utils',
    ];
    const DFLT_CONC: C[] = ['off', '4', '8', 'auto'];
    const DFLT_RUNS = 3;
    const pad = (s: string, n: number) =>
    s.length >= n ? s : s + ' '.repeat(n - s.length);
    const exists = async (p: string) => !!(await stat(p).catch(() => null));
    const ensureDir = (d: string) => mkdir(d, { recursive: true });

    function args() {
    const a = process.argv.slice(2);
    const get = (n: string) =>
    a.find(x => x.startsWith(`--${n}=`))?.split('=')[1];
    const targets = get('targets')?.split(',').filter(Boolean) ?? DFLT_TARGETS;
    const conc =
    (get('concurrency')?.split(',').filter(Boolean) as C[] | undefined) ??
    DFLT_CONC;
    const runs = Number.parseInt(get('runs') ?? `${DFLT_RUNS}`, 10);
    const outDir = get('outDir') ?? path.join('tools', 'eslint-perf', 'results');
    const verbose = a.includes('--verbose') || get('verbose') === 'true';
    const useLocalConfig = get('useLocalConfig') === 'false' ? false : true;
    const tsOnly = get('tsOnly') === 'false' ? false : true;
    return { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly };
    }

    async function sys() {
    const nx = await exec('npx nx --version')
    .then(r => r.stdout.trim().split('\n')[0])
    .catch(() => null);
    return {
    timestamp: new Date().toISOString(),
    system: {
    os: os.platform(),
    osVersion: os.release(),
    architecture: os.arch(),
    cpuCores: os.cpus()?.length ?? 0,
    totalMemGb: Math.round((os.totalmem() / 1024 ** 3) * 100) / 100,
    hostname: os.hostname(),
    },
    software: {
    nodeVersion: process.version,
    npmVersion: (await exec('npm --version')).stdout.trim(),
    eslintVersion: (await exec('npx eslint --version')).stdout.trim(),
    nxVersion: nx,
    },
    };
    }

    async function count(dir: string, exts: string[]) {
    let n = 0;
    const w = async (d: string): Promise<void> => {
    const es = await readdir(d, { withFileTypes: true });
    for (const e of es) {
    const p = path.join(d, e.name);
    if (e.isDirectory()) {
    if (['node_modules', 'dist', 'coverage'].includes(e.name)) continue;
    await w(p);
    } else if (e.isFile() && exts.some(ext => e.name.endsWith(ext))) n++;
    }
    };
    await w(dir);
    return n;
    }
    async function info(t: string): Promise<TE> {
    const abs = path.resolve(t);
    if (!(await exists(abs)))
    return { target: t, tsFiles: 0, jsFiles: 0, totalFiles: 0 };
    const ts = await count(abs, ['.ts', '.tsx']);
    const js = await count(abs, ['.js', '.jsx', '.mjs', '.cjs']);
    return { target: t, tsFiles: ts, jsFiles: js, totalFiles: ts + js };
    }
    type TE = TI;

    const cmd = (
    t: string,
    c: C,
    o: { local: boolean; ts: boolean; json: boolean },
    ) =>
    `npx eslint${o.local ? ` --config=${JSON.stringify(path.join(t, 'eslint.config.js'))}` : ''} --concurrency=${c} ${o.json ? '--format=json' : '--format=stylish'} ${[o.ts ? path.join(t, '**', '*.ts') : t].map(p => JSON.stringify(p)).join(' ')}`;

    async function once(
    t: string,
    c: C,
    i: number,
    v: boolean,
    local: boolean,
    ts: boolean,
    ): Promise<Run> {
    const s = process.hrtime.bigint();
    const k = cmd(t, c, { local, ts, json: true });
    let out = '',
    err = '';
    try {
    const r = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    out = r.stdout;
    err = r.stderr;
    } catch (e: any) {
    out = e.stdout ?? '';
    err = e.stderr ?? '';
    }
    if (v) {
    console.log(` $ ${k}`);
    if (err.trim()) {
    console.log(' [stderr]');
    console.log(
    err
    .split('\n')
    .map(l => ` ${l}`)
    .join('\n'),
    );
    }
    }
    const d = Number(process.hrtime.bigint() - s) / 1_000_000_000;
    let files = 0,
    errors = 0,
    warnings = 0;
    try {
    const j = JSON.parse(out) as Array<{
    errorCount: number;
    warningCount: number;
    }>;
    files = j.length;
    for (const r of j) {
    errors += r.errorCount || 0;
    warnings += r.warningCount || 0;
    }
    } catch {}
    const warns = err.includes('ESLintPoorConcurrencyWarning')
    ? ['ESLintPoorConcurrencyWarning']
    : [];
    return {
    target: t,
    concurrency: c,
    run: i,
    timing: {
    durationSeconds: d,
    realTimeSeconds: null,
    userTimeSeconds: null,
    sysTimeSeconds: null,
    },
    eslintResults: {
    filesProcessed: files,
    errors,
    warnings,
    eslintWarnings: warns,
    },
    timestamp: new Date().toISOString(),
    };
    }

    const statz = (xs: number[]): Stats => {
    const n = xs.length,
    min = Math.min(...xs),
    max = Math.max(...xs),
    avg = xs.reduce((a, b) => a + b, 0) / n,
    sd = Math.sqrt(xs.reduce((a, v) => a + (v - avg) ** 2, 0) / n);
    return {
    runs: n,
    min,
    max,
    avg: Number(avg.toFixed(3)),
    stdDev: Number(sd.toFixed(3)),
    };
    };

    async function stylish(t: string) {
    const k = cmd(t, 'off', { local: true, ts: true, json: false });
    try {
    const { stdout, stderr } = await exec(k, { maxBuffer: 1024 * 1024 * 200 });
    if (stdout.trim()) {
    console.log(' [stylish output]');
    console.log(
    stdout
    .split('\n')
    .slice(0, 300)
    .map(l => ` ${l}`)
    .join('\n'),
    );
    }
    if (stderr.trim()) {
    console.log(' [stylish stderr]');
    console.log(
    stderr
    .split('\n')
    .map(l => ` ${l}`)
    .join('\n'),
    );
    }
    } catch (e: any) {
    const o = e.stdout ?? '',
    er = e.stderr ?? '';
    if (o.trim()) {
    console.log(' [stylish output]');
    console.log(
    o
    .split('\n')
    .slice(0, 300)
    .map((l: string) => ` ${l}`)
    .join('\n'),
    );
    }
    if (er.trim()) {
    console.log(' [stylish stderr]');
    console.log(
    er
    .split('\n')
    .map((l: string) => ` ${l}`)
    .join('\n'),
    );
    }
    }
    }

    async function main() {
    const { targets, conc, runs, outDir, verbose, useLocalConfig, tsOnly } =
    args();
    await ensureDir(outDir);
    const si = await sys(),
    ts = new Date().toISOString().replace(/[:.]/g, '-');
    const resPath = path.join(outDir, `eslint-benchmark-${ts}.json`),
    sumPath = path.join(outDir, `eslint-benchmark-${ts}.summary.md`);
    const results: any[] = [];
    await writeFile(
    path.join(outDir, `system-info-${ts}.json`),
    JSON.stringify(si, null, 2),
    );
    for (const t of targets) {
    if (!(await exists(path.resolve(t)))) {
    console.warn(`Skipping missing target: ${t}`);
    continue;
    }
    const ti = await info(t);
    console.log(
    `\n📁 Target: ${t} (files: ${ti.totalFiles}, ts: ${ti.tsFiles}, js: ${ti.jsFiles})`,
    );
    if (verbose) await stylish(t);
    for (const c of conc) {
    console.log(` 🔧 Concurrency: ${c}`);
    const rs: Run[] = [];
    for (let i = 1; i <= runs; i++) {
    console.log(` Run ${i}/${runs} ...`);
    const r = await once(t, c, i, verbose, useLocalConfig, tsOnly);
    rs.push(r);
    console.log(
    ` Time: ${r.timing.durationSeconds.toFixed(3)}s, Files: ${r.eslintResults.filesProcessed}, Errors: ${r.eslintResults.errors}, Warnings: ${r.eslintResults.warnings}${r.eslintResults.eslintWarnings.length ? ' ⚠️ ' + r.eslintResults.eslintWarnings.join(',') : ''}`,
    );
    }
    const s = statz(rs.map(r => r.timing.durationSeconds));
    results.push({
    target: t,
    targetInfo: ti,
    concurrency: c,
    statistics: s,
    runs: rs,
    });
    console.log(
    ` ✅ Avg: ${s.avg}s (min ${s.min.toFixed(3)}s, max ${s.max.toFixed(3)}s, ±${s.stdDev}s)`,
    );
    }
    }
    await writeFile(
    resPath,
    JSON.stringify({ systemInfo: si, results }, null, 2),
    );

    // Build Markdown summary (system info, fastest table, per-target breakdown)
    const tset = Array.from(new Set(results.map((r: any) => r.target)));
    const rows = tset.map(t => {
    const xs = results.filter((r: any) => r.target === t);
    const best = xs.reduce((a: any, b: any) =>
    a.statistics.avg <= b.statistics.avg ? a : b,
    );
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const speed = base ? (base / best.statistics.avg).toFixed(2) + 'x' : 'n/a';
    return {
    t,
    bestConc: best.concurrency as C,
    bestAvg: Number(best.statistics.avg.toFixed(3)),
    base,
    speed,
    };
    });

    const md: string[] = [];
    md.push('# ESLint Concurrency Benchmark Report');
    md.push('');
    md.push(`Generated: ${new Date().toString()}`);
    md.push('');
    md.push('## System');
    md.push(`- **OS**: ${si.system.os} ${si.system.osVersion}`);
    md.push(`- **CPU Cores**: ${si.system.cpuCores}`);
    md.push(`- **Memory**: ${si.system.totalMemGb} GB`);
    md.push(`- **Node**: \\`${si.software.nodeVersion}\\``);
    md.push(`- **ESLint**: \\`${si.software.eslintVersion}\\``);
    if (si.software.nxVersion) md.push(`- **Nx**: \\`${si.software.nxVersion}\\``);
    md.push('');

    md.push('## Fastest per target');
    md.push('');
    md.push('| Target | Best | Avg (s) | Baseline (s) | Speedup |');
    md.push('|---|:---:|---:|---:|---:|');
    for (const r of rows) {
    md.push(`| \\`${r.t}\\` | **${r.bestConc}** | **${r.bestAvg.toFixed(3)}** | ${r.base ? r.base.toFixed(3) : 'n/a'} | **${r.speed}** |`);
    }
    md.push('');

    md.push('## Per-target breakdown');
    md.push('Best rows are marked with ★.');
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base = xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const bestAvg = Math.min(...xs.map((r: any) => r.statistics.avg));
    md.push('');
    md.push(`### \\`${t}\\``);
    md.push('');
    md.push('| Concurrency | Avg (s) | StdDev | Speedup |');
    md.push('|:-----------:|---:|---:|---:|');
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const isBest = Math.abs(r.statistics.avg - bestAvg) < 1e-6;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    const row = `| \\`${String(c)}\\` | ${r.statistics.avg.toFixed(3)} | ${r.statistics.stdDev.toFixed(3)} | ${sp} | ${isBest ? '' : ''}`;
    md.push(isBest ? row.replace(/\| ([^|]+) \|/, match => match.replace(/([^|]+)/, '**$1**')) : row);
    }
    }

    await writeFile(sumPath, md.join('\n'));
    console.log('\n✅ Benchmark complete');
    console.log(`Raw results: ${resPath}`);
    console.log(`Summary: ${sumPath}`);
    // Reuse computed tset/rows for terminal tables
    const header = `${pad('Target', 28)} ${pad('Best', 6)} ${pad('Avg(s)', 8)} ${pad('Baseline(s)', 12)} Speedup`;
    console.log('\nFastest per target:');
    console.log(header);
    console.log('-'.repeat(header.length));
    for (const r of rows)
    console.log(
    `${pad(r.t, 28)} ${pad(String(r.bestConc), 6)} ${pad(r.bestAvg.toFixed(3), 8)} ${pad(r.base ? r.base.toFixed(3) : 'n/a', 12)} ${r.speed}`,
    );
    console.log('\nPer-target breakdown (best marked with ★):');
    for (const t of tset) {
    const xs = results.filter((r: any) => r.target === t);
    const base =
    xs.find((r: any) => r.concurrency === 'off')?.statistics.avg ?? null;
    const best = Math.min(...xs.map((r: any) => r.statistics.avg));
    console.log(`\n${t}`);
    const h2 = `${pad('Concurrency', 12)} ${pad('Avg(s)', 8)} ${pad('StdDev', 8)} ${pad('Speedup', 8)} Mark`;
    console.log(h2);
    console.log('-'.repeat(h2.length));
    for (const c of Array.from(new Set(xs.map((r: any) => r.concurrency)))) {
    const r = xs.find((q: any) => q.concurrency === c)!;
    const sp = base ? `${(base / r.statistics.avg).toFixed(2)}x` : 'n/a';
    console.log(
    `${pad(String(c), 12)} ${pad(r.statistics.avg.toFixed(3), 8)} ${pad(r.statistics.stdDev.toFixed(3), 8)} ${pad(sp, 8)} ${Math.abs(r.statistics.avg - best) < 1e-6 ? '' : ''}`,
    );
    }
    }
    }

    main().catch(e => {
    console.error(e);
    process.exitCode = 1;
    });
    ```