/** * Benchmark-specific statistical analysis. * Uses the general stats utilities from `stats.ts` for timing/performance analysis. * All timing values are in nanoseconds. * * @module */ /** * Minimal stats interface for comparison. * This allows comparing stats from different sources (e.g., loaded baselines). */ export interface BenchmarkStatsComparable { mean_ns: number; std_dev_ns: number; sample_size: number; confidence_interval_ns: [number, number]; } /** * Effect size magnitude interpretation (Cohen's d). */ export type EffectMagnitude = 'negligible' | 'small' | 'medium' | 'large'; /** * Result from comparing two benchmark stats. */ export interface BenchmarkComparison { /** Which benchmark is faster ('a', 'b', or 'equal' if difference is negligible) */ faster: 'a' | 'b' | 'equal'; /** How much faster the winner is (e.g., 1.5 means 1.5x faster) */ speedup_ratio: number; /** Whether the difference is both statistically and practically significant */ significant: boolean; /** P-value from Welch's t-test (lower = more confident the difference is real) */ p_value: number; /** Percentage difference between means as a ratio (0.05 = 5%, 1.0 = 100%) */ percent_difference: number; /** Cohen's d effect size (informational — not used for classification) */ effect_size: number; /** Interpretation of practical significance based on percentage difference */ effect_magnitude: EffectMagnitude; /** * Whether the 95% confidence intervals of the two means overlap. * * **Informational only — do not use this field to infer significance.** * Two means with overlapping 95% CIs can still differ significantly at * p<0.05 (overlap of up to ~25% of CI width is consistent with * significance); conversely, non-overlapping CIs are slightly *stronger* * than the standard p<0.05 bar but the relationship is not strict. * Use `significant` and `p_value` for classification. This field is * exposed for consumers who want to render CIs side-by-side and need * the visual overlap check. * * Note: the underlying CIs are computed with a z-score (1.96) rather * than the strict t-score, so at small n the CIs are slightly narrow * — overlap is reported less often than a t-based CI would. Effect is * ~2-3% at the n=30 floor after Bessel's correction on `std_dev_ns`. */ ci_overlap: boolean; /** Human-readable interpretation of the comparison */ recommendation: string; } /** * Options for benchmark comparison. */ export interface BenchmarkCompareOptions { /** Significance level for hypothesis testing (default: 0.05) */ alpha?: number; /** * Minimum percentage difference to consider practically meaningful, as a ratio. * Below this threshold, differences are classified as 'negligible' and * `significant` is forced to `false`, regardless of p-value. * This prevents the t-test's oversensitivity at large sample sizes from * flagging system-level noise (thermal throttle, OS scheduler, cache pressure) * as meaningful differences. * * Effect magnitude thresholds scale from this value: * negligible < min, small < min*3, medium < min*5, large >= min*5. * * Default: 0.10 (10%). */ min_percent_difference?: number; } /** * Complete statistical analysis of timing measurements. * Includes outlier detection, descriptive statistics, and performance metrics. * All timing values are in nanoseconds. * * **Outliers are treated asymmetrically**, because high and low outliers in * timing data mean different things: * * - Upper-tail order statistics (`max_ns`, `p75_ns`–`p99_ns`) are computed over * the **raw** valid timings — high outliers (GC pauses, slow paths) are real * latency events, so the tail stays honest and p99 reflects real events * rather than a pre-stripped distribution. * - `min_ns` is computed over the **MAD-cleaned** timings — nothing runs faster * than its true cost, so a low outlier is an invalid measurement, not a fast * run, and reporting it as the best case would mislead. * - Central-tendency statistics (`mean_ns`, `std_dev_ns`, `cv`, * `confidence_interval_ns`, `ops_per_second`) are computed over the * **MAD-cleaned** timings so the Welch's-t comparison keeps a stable mean. * * `p50_ns` (median) uses raw timings to stay paired with the percentile family; * being robust, it's unaffected in practice. `outlier_ratio` reports how heavy * the tail was either way. `sample_size` is the cleaned count behind central * tendency and `min_ns`; the upper-tail order statistics use all valid timings * (`sample_size` + `outliers_ns.length`); `raw_sample_size` is the total input * count including the `failed_iterations` invalid values that were filtered out. */ export declare class BenchmarkStats { /** Mean (average) time in nanoseconds (over MAD-cleaned samples) */ readonly mean_ns: number; /** 50th percentile (median) time in nanoseconds (over raw samples) */ readonly p50_ns: number; /** Standard deviation in nanoseconds (over MAD-cleaned samples) */ readonly std_dev_ns: number; /** Minimum time in nanoseconds (over MAD-cleaned samples) */ readonly min_ns: number; /** Maximum time in nanoseconds (over raw samples) */ readonly max_ns: number; /** 75th percentile in nanoseconds (over raw samples) */ readonly p75_ns: number; /** 90th percentile in nanoseconds (over raw samples) */ readonly p90_ns: number; /** 95th percentile in nanoseconds (over raw samples) */ readonly p95_ns: number; /** 99th percentile in nanoseconds (over raw samples) */ readonly p99_ns: number; /** Coefficient of variation (std_dev / mean) */ readonly cv: number; /** 95% confidence interval for the mean in nanoseconds */ readonly confidence_interval_ns: [number, number]; /** Array of detected outlier values in nanoseconds */ readonly outliers_ns: Array; /** Ratio of outliers to total samples */ readonly outlier_ratio: number; /** Number of valid samples after outlier removal (population for central tendency and `min_ns`) */ readonly sample_size: number; /** Number of input samples before filtering invalid/outlier values */ readonly raw_sample_size: number; /** Operations per second (NS_PER_SEC / mean_ns) */ readonly ops_per_second: number; /** Number of failed iterations (NaN, Infinity, or negative values) */ readonly failed_iterations: number; constructor(timings_ns: Array); /** * Format stats as a human-readable string. */ toString(): string; } /** * Compare two benchmark results for practical and statistical significance. * Uses percentage difference for effect magnitude classification, with Welch's * t-test for statistical confidence. Cohen's d is computed as an informational * metric but does not drive classification — its thresholds (0.2/0.5/0.8) are * calibrated for social science and produce false positives in benchmarking * where within-run variance is tight. * * @param a - first benchmark stats (or any object with required properties) * @param b - second benchmark stats (or any object with required properties) * @returns comparison result with significance, effect size, and recommendation * * @example * ```ts * const comparison = benchmark_stats_compare(result_a.stats, result_b.stats); * if (comparison.significant) { * console.log(`${comparison.faster} is ${comparison.speedup_ratio.toFixed(2)}x faster`); * } * ``` */ export declare const benchmark_stats_compare: (a: BenchmarkStatsComparable, b: BenchmarkStatsComparable, options?: BenchmarkCompareOptions) => BenchmarkComparison; //# sourceMappingURL=benchmark_stats.d.ts.map