From ce2d733f85bfc961645e9a2ba1e3af54e5325b3e Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 19 Dec 2025 10:48:18 -0800 Subject: [PATCH] fix: Fix warming and configuration change issues with detectDeadCodeElimination=true Avoid configuration changes mid-run, and move warnings to the top of the output. As previously implemented, the worker mode warnings would be issued once per benchmark, interlaced with them, and with DCE enabled wouldn't issue a warning at all. Putting the warnings in the middle of the test output is more likely to be missed by a user, lost in the noise. This change also settles the issue of which plugins we are running to the constructor, also avoiding 1) re-writing the benchmark string after creation 2) rewriting the benchmark string after warming has already supposedly completed --- lib/index.js | 59 ++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/lib/index.js b/lib/index.js index e3e0886..e5905c5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -141,31 +141,49 @@ class Suite { } this.#useWorkers = options.useWorkers || false; + this.#benchmarkMode = options.benchmarkMode || "ops"; + validateBenchmarkMode(this.#benchmarkMode, "options.benchmarkMode"); - // DCE detection is opt-in to avoid breaking changes - const dceEnabled = options.detectDeadCodeElimination === true; - if (dceEnabled) { - this.#dceDetector = new DeadCodeEliminationDetectionPlugin( - options.dceThreshold ? { threshold: options.dceThreshold } : {}, + if (this.#useWorkers && this.#benchmarkMode === "time") { + console.warn( + "Warning: Worker mode currently doesn't fully support 'time' benchmarkMode.", ); } - // Plugin setup: If DCE detection is enabled, default to no plugins (allow optimization) - // Otherwise, use V8NeverOptimizePlugin as the default + // DCE detection is opt-in to avoid breaking changes + let dceEnabled = false; + + if (options.detectDeadCodeElimination === true) { + if (this.#useWorkers) { + console.warn( + "Warning: Worker mode currently doesn't support detectDeadCodeElimination=true.", + ); + } else { + dceEnabled = true; + } + } + + let plugins = []; + if (options?.plugins) { validateArray(options.plugins, "plugin"); validatePlugins(options.plugins); - this.#plugins = options.plugins; - } else if (dceEnabled) { + plugins = [...options.plugins]; + } else if (!dceEnabled) { // DCE detection requires optimization to be enabled, so no default plugins - this.#plugins = []; - } else { // Default behavior - use V8NeverOptimizePlugin - this.#plugins = [new V8NeverOptimizePlugin()]; + plugins = [new V8NeverOptimizePlugin()]; } - this.#benchmarkMode = options.benchmarkMode || "ops"; - validateBenchmarkMode(this.#benchmarkMode, "options.benchmarkMode"); + if (dceEnabled) { + this.#dceDetector = new DeadCodeEliminationDetectionPlugin( + options.dceThreshold ? { threshold: options.dceThreshold } : {}, + ); + + plugins.push(this.#dceDetector); + } + + this.#plugins = plugins; this.#reporterOptions = options.reporterOptions || { printHeader: true, @@ -278,14 +296,6 @@ class Suite { for (let i = 0; i < this.#benchmarks.length; ++i) { const benchmark = this.#benchmarks[i]; - // Add DCE detector to benchmark plugins if enabled - if (this.#dceDetector && this.#benchmarkMode === "ops") { - const originalPlugins = benchmark.plugins; - benchmark.plugins = [...benchmark.plugins, this.#dceDetector]; - // Regenerate function string with new plugins - benchmark.fnStr = createFnString(benchmark); - } - // Warmup is calculated to reduce noise/bias on the results const initialIterations = await getInitialIterations(benchmark); debugBench( @@ -294,11 +304,6 @@ class Suite { let result; if (this.#useWorkers) { - if (this.#benchmarkMode === "time") { - console.warn( - "Warning: Worker mode currently doesn't fully support 'time' benchmarkMode.", - ); - } result = await this.runWorkerBenchmark(benchmark, initialIterations); } else { result = await runBenchmark(