diff --git a/lib/bencher_adapter/src/adapters/js/mod.rs b/lib/bencher_adapter/src/adapters/js/mod.rs index c9f4e6abeb..d551b33445 100644 --- a/lib/bencher_adapter/src/adapters/js/mod.rs +++ b/lib/bencher_adapter/src/adapters/js/mod.rs @@ -1,21 +1,25 @@ pub mod benchmark; pub mod time; +pub mod vitest; use crate::{Adaptable, AdapterResults, Settings}; use benchmark::AdapterJsBenchmark; use time::AdapterJsTime; +use vitest::AdapterJsVitest; pub struct AdapterJs; impl Adaptable for AdapterJs { fn parse(input: &str, settings: Settings) -> Option { - AdapterJsBenchmark::parse(input, settings).or_else(|| AdapterJsTime::parse(input, settings)) + AdapterJsBenchmark::parse(input, settings) + .or_else(|| AdapterJsTime::parse(input, settings)) + .or_else(|| AdapterJsVitest::parse(input, settings)) } } #[cfg(test)] mod test_js { - use super::{AdapterJs, time::test_js_time}; + use super::{AdapterJs, time::test_js_time, vitest::test_js_vitest}; use crate::adapters::{js::benchmark::test_js_benchmark, test_util::convert_file_path}; #[test] @@ -29,4 +33,10 @@ mod test_js { let results = convert_file_path::("./tool_output/js/time/four.txt"); test_js_time::validate_adapter_js_time(&results); } + + #[test] + fn adapter_js_vitest() { + let results = convert_file_path::("./tool_output/js/vitest/four.json"); + test_js_vitest::validate_adapter_js_vitest(&results); + } } diff --git a/lib/bencher_adapter/src/adapters/js/vitest.rs b/lib/bencher_adapter/src/adapters/js/vitest.rs new file mode 100644 index 0000000000..c7d7155765 --- /dev/null +++ b/lib/bencher_adapter/src/adapters/js/vitest.rs @@ -0,0 +1,293 @@ +use bencher_json::{BenchmarkName, JsonNewMetric, project::report::JsonAverage}; +use serde::Deserialize; + +use crate::{ + Adaptable, Settings, + adapters::util::{Units, latency_as_nanos, throughput_as_secs}, + results::adapter_results::{AdapterMeasure, AdapterResults}, +}; + +pub struct AdapterJsVitest; + +impl Adaptable for AdapterJsVitest { + fn parse(input: &str, settings: Settings) -> Option { + serde_json::from_str::(input) + .ok()? + .convert(settings) + } +} + +/// The JSON report emitted by `vitest bench --outputJson `. +/// See `createBenchmarkJsonReport` in Vitest's `benchmark/json-formatter.ts`. +#[derive(Debug, Clone, Deserialize)] +struct Vitest { + files: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +struct File { + // `filepath` is intentionally ignored: it is an absolute, machine-specific + // path and therefore not portable across CI runners. Vitest's `fullName` + // already begins with the file's project-relative path (see `getNames` in + // `@vitest/runner`), so benchmark names stay unique across files without it. + groups: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +struct Group { + #[serde(rename = "fullName")] + full_name: String, + benchmarks: Vec, +} + +/// A single benchmark result. This is Tinybench's `TaskResult` plus the +/// `name`/`median` fields that Vitest adds. Unused fields are ignored. +#[derive(Debug, Clone, Deserialize)] +struct Benchmark { + name: BenchmarkName, + /// Operations per second (throughput). + hz: f64, + /// Average time per operation in milliseconds (latency). + mean: f64, + /// Median time per operation in milliseconds (latency). + median: f64, + /// Standard deviation of the samples in milliseconds. + sd: f64, + /// Relative margin of error as a percentage. + rme: f64, +} + +impl Vitest { + fn convert(self, settings: Settings) -> Option { + let mut benchmark_metrics = Vec::new(); + for file in self.files { + for group in file.groups { + for benchmark in group.benchmarks { + let Benchmark { + name, + hz, + mean, + median, + sd, + rme, + } = benchmark; + let benchmark_name = combine_name(&group.full_name, name); + + // Latency: milliseconds -> nanoseconds. + // For the mean, the spread is the standard deviation. + // Vitest does not provide an interquartile range, so the + // median is reported without a lower or upper value. + let latency = match settings.average.unwrap_or_default() { + JsonAverage::Mean => { + let value = latency_as_nanos(mean, Units::Milli); + let spread = latency_as_nanos(sd, Units::Milli); + JsonNewMetric { + value, + lower_value: Some(value - spread), + upper_value: Some(value + spread), + } + }, + JsonAverage::Median => JsonNewMetric { + value: latency_as_nanos(median, Units::Milli), + lower_value: None, + upper_value: None, + }, + }; + + // Throughput: operations per second. + // The bounds are derived from the relative margin of error. + let value = throughput_as_secs(hz, Units::Sec); + let error = value * (rme / 100.0); + let throughput = JsonNewMetric { + value, + lower_value: Some(value - error), + upper_value: Some(value + error), + }; + + benchmark_metrics.push(( + benchmark_name, + vec![ + AdapterMeasure::Latency(latency), + AdapterMeasure::Throughput(throughput), + ], + )); + } + } + } + + AdapterResults::new_measures(benchmark_metrics) + } +} + +/// Join the suite `full_name` and the benchmark `name` into a single benchmark +/// name (e.g. `"math > fibonacci > fib(10)"`), matching the `" > "` separator +/// Vitest itself uses within `fullName`. Falls back to the leaf `name` when the +/// suite name is empty or the combined name would exceed `BenchmarkName::MAX_LEN`. +fn combine_name(full_name: &str, name: BenchmarkName) -> BenchmarkName { + if full_name.is_empty() { + name + } else { + format!("{full_name} > {name}") + .parse::() + .unwrap_or(name) + } +} + +#[cfg(test)] +pub(crate) mod test_js_vitest { + use bencher_json::project::report::JsonAverage; + use ordered_float::OrderedFloat; + use pretty_assertions::assert_eq; + + use crate::{ + AdapterResults, Settings, + adapters::test_util::{convert_file_path, convert_file_path_median, opt_convert_file_path}, + results::adapter_metrics::AdapterMetrics, + }; + + use super::AdapterJsVitest; + + fn convert_js_vitest(suffix: &str) -> AdapterResults { + let file_path = file_path(suffix); + convert_file_path::(&file_path) + } + + fn convert_js_vitest_median(suffix: &str) -> AdapterResults { + let file_path = file_path(suffix); + convert_file_path_median::(&file_path) + } + + fn file_path(suffix: &str) -> String { + format!("./tool_output/js/vitest/{suffix}.json") + } + + fn validate_measure( + metrics: &AdapterMetrics, + slug: &str, + value: f64, + lower_value: Option, + upper_value: Option, + ) { + let metric = metrics.get(slug).unwrap(); + assert_eq!(metric.value, OrderedFloat::from(value)); + assert_eq!(metric.lower_value, lower_value.map(OrderedFloat::from)); + assert_eq!(metric.upper_value, upper_value.map(OrderedFloat::from)); + } + + #[test] + fn adapter_js_vitest_two() { + let results = convert_js_vitest("two"); + assert_eq!(results.inner.len(), 2); + + let metrics = results.get("math.bench.ts > math > add").unwrap(); + assert_eq!(metrics.inner.len(), 2); + validate_measure( + metrics, + "latency", + 1_000_000.0, + Some(750_000.0), + Some(1_250_000.0), + ); + validate_measure(metrics, "throughput", 1_000.0, Some(750.0), Some(1_250.0)); + + let metrics = results.get("math.bench.ts > math > subtract").unwrap(); + assert_eq!(metrics.inner.len(), 2); + validate_measure( + metrics, + "latency", + 2_000_000.0, + Some(1_500_000.0), + Some(2_500_000.0), + ); + validate_measure(metrics, "throughput", 500.0, Some(375.0), Some(625.0)); + } + + #[test] + fn adapter_js_vitest_four() { + let four = "four"; + let file_path = file_path(four); + + let results = convert_js_vitest(four); + validate_adapter_js_vitest(&results); + + // An explicit mean average matches the default. + let results = opt_convert_file_path::( + &file_path, + Settings { + average: Some(JsonAverage::Mean), + }, + ) + .unwrap(); + validate_adapter_js_vitest(&results); + + let results = convert_js_vitest_median(four); + validate_adapter_js_vitest_median(&results); + } + + pub fn validate_adapter_js_vitest(results: &AdapterResults) { + assert_eq!(results.inner.len(), 4); + + let metrics = results.get("fib.bench.ts > fibonacci > fib(10)").unwrap(); + assert_eq!(metrics.inner.len(), 2); + validate_measure( + metrics, + "latency", + 1_000_000.0, + Some(750_000.0), + Some(1_250_000.0), + ); + validate_measure(metrics, "throughput", 1_000.0, Some(750.0), Some(1_250.0)); + + let metrics = results.get("fib.bench.ts > fibonacci > fib(20)").unwrap(); + validate_measure( + metrics, + "latency", + 2_000_000.0, + Some(1_500_000.0), + Some(2_500_000.0), + ); + validate_measure(metrics, "throughput", 500.0, Some(375.0), Some(625.0)); + + let metrics = results.get("sort.bench.ts > sorting > normal").unwrap(); + validate_measure( + metrics, + "latency", + 5_000_000.0, + Some(3_750_000.0), + Some(6_250_000.0), + ); + validate_measure(metrics, "throughput", 200.0, Some(150.0), Some(250.0)); + + let metrics = results.get("sort.bench.ts > sorting > reverse").unwrap(); + validate_measure( + metrics, + "latency", + 10_000_000.0, + Some(7_500_000.0), + Some(12_500_000.0), + ); + validate_measure(metrics, "throughput", 100.0, Some(75.0), Some(125.0)); + } + + fn validate_adapter_js_vitest_median(results: &AdapterResults) { + assert_eq!(results.inner.len(), 4); + + // Latency uses the median with no spread (Vitest provides no IQR); + // throughput is unaffected by the average. + let metrics = results.get("fib.bench.ts > fibonacci > fib(10)").unwrap(); + validate_measure(metrics, "latency", 750_000.0, None, None); + validate_measure(metrics, "throughput", 1_000.0, Some(750.0), Some(1_250.0)); + + let metrics = results.get("fib.bench.ts > fibonacci > fib(20)").unwrap(); + validate_measure(metrics, "latency", 1_500_000.0, None, None); + validate_measure(metrics, "throughput", 500.0, Some(375.0), Some(625.0)); + + let metrics = results.get("sort.bench.ts > sorting > normal").unwrap(); + validate_measure(metrics, "latency", 4_000_000.0, None, None); + validate_measure(metrics, "throughput", 200.0, Some(150.0), Some(250.0)); + + let metrics = results.get("sort.bench.ts > sorting > reverse").unwrap(); + validate_measure(metrics, "latency", 8_000_000.0, None, None); + validate_measure(metrics, "throughput", 100.0, Some(75.0), Some(125.0)); + } +} diff --git a/lib/bencher_adapter/src/adapters/magic.rs b/lib/bencher_adapter/src/adapters/magic.rs index 1facef2ad9..591364f5de 100644 --- a/lib/bencher_adapter/src/adapters/magic.rs +++ b/lib/bencher_adapter/src/adapters/magic.rs @@ -31,7 +31,7 @@ mod test_magic { dart::benchmark_harness::test_dart_benchmark_harness, go::bench::test_go_bench, java::jmh::test_java_jmh, - js::{benchmark::test_js_benchmark, time::test_js_time}, + js::{benchmark::test_js_benchmark, time::test_js_time, vitest::test_js_vitest}, json::test_json, python::{asv::test_python_asv, pytest::test_python_pytest}, ruby::benchmark::test_ruby_benchmark, @@ -104,6 +104,12 @@ mod test_magic { test_js_time::validate_adapter_js_time(&results); } + #[test] + fn adapter_magic_js_vitest() { + let results = convert_file_path::("./tool_output/js/vitest/four.json"); + test_js_vitest::validate_adapter_js_vitest(&results); + } + #[test] fn adapter_python_asv() { let results = convert_file_path::("./tool_output/python/asv/six.txt"); diff --git a/lib/bencher_adapter/src/lib.rs b/lib/bencher_adapter/src/lib.rs index 79caf6580d..193c3fafde 100644 --- a/lib/bencher_adapter/src/lib.rs +++ b/lib/bencher_adapter/src/lib.rs @@ -11,7 +11,7 @@ use adapters::{ dart::{AdapterDart, benchmark_harness::AdapterDartBenchmarkHarness}, go::{AdapterGo, bench::AdapterGoBench}, java::{AdapterJava, jmh::AdapterJavaJmh}, - js::{AdapterJs, benchmark::AdapterJsBenchmark, time::AdapterJsTime}, + js::{AdapterJs, benchmark::AdapterJsBenchmark, time::AdapterJsTime, vitest::AdapterJsVitest}, json::AdapterJson, magic::AdapterMagic, python::{AdapterPython, asv::AdapterPythonAsv, pytest::AdapterPythonPytest}, @@ -54,6 +54,7 @@ impl Adaptable for Adapter { Adapter::Js => AdapterJs::parse(input, settings), Adapter::JsBenchmark => AdapterJsBenchmark::parse(input, settings), Adapter::JsTime => AdapterJsTime::parse(input, settings), + Adapter::JsVitest => AdapterJsVitest::parse(input, settings), Adapter::Python => AdapterPython::parse(input, settings), Adapter::PythonAsv => AdapterPythonAsv::parse(input, settings), Adapter::PythonPytest => AdapterPythonPytest::parse(input, settings), diff --git a/lib/bencher_adapter/src/results/adapter_results.rs b/lib/bencher_adapter/src/results/adapter_results.rs index d15f2a5adc..8bcdc81f00 100644 --- a/lib/bencher_adapter/src/results/adapter_results.rs +++ b/lib/bencher_adapter/src/results/adapter_results.rs @@ -187,6 +187,36 @@ impl AdapterResults { ) } + /// Create results where each benchmark may report multiple default measures + /// (e.g. both `Latency` and `Throughput`). + pub fn new_measures( + benchmark_metrics: Vec<(BenchmarkName, Vec)>, + ) -> Option { + if benchmark_metrics.is_empty() { + return None; + } + + let mut results_map = HashMap::new(); + for (benchmark_name, measures) in benchmark_metrics { + let metrics_value = results_map + .entry(BenchmarkNameId::new_name(benchmark_name)) + .or_insert_with(AdapterMetrics::default); + for measure in measures { + let (resource_id, metric) = match measure { + AdapterMeasure::Latency(json_metric) => { + (built_in::default::Latency::name_id(), json_metric) + }, + AdapterMeasure::Throughput(json_metric) => { + (built_in::default::Throughput::name_id(), json_metric) + }, + }; + metrics_value.inner.insert(resource_id, metric); + } + } + + Some(results_map.into()) + } + pub fn new_iai(benchmark_metrics: Vec<(BenchmarkName, Vec)>) -> Option { if benchmark_metrics.is_empty() { return None; diff --git a/lib/bencher_adapter/tool_output/js/vitest/four.json b/lib/bencher_adapter/tool_output/js/vitest/four.json new file mode 100644 index 0000000000..2a0d03f37b --- /dev/null +++ b/lib/bencher_adapter/tool_output/js/vitest/four.json @@ -0,0 +1,124 @@ +{ + "files": [ + { + "filepath": "/home/runner/project/fib.bench.ts", + "groups": [ + { + "fullName": "fib.bench.ts > fibonacci", + "benchmarks": [ + { + "id": "fib.bench.ts_0_0", + "name": "fib(10)", + "rank": 1, + "sampleCount": 93, + "totalTime": 521.4, + "min": 0.8, + "max": 1.5, + "hz": 1000.0, + "period": 1.0, + "samples": [], + "mean": 1.0, + "variance": 0.0625, + "sd": 0.25, + "sem": 0.0259, + "df": 92, + "critical": 1.986, + "moe": 0.0514, + "rme": 25.0, + "p75": 1.05, + "p99": 1.4, + "p995": 1.45, + "p999": 1.5, + "median": 0.75 + }, + { + "id": "fib.bench.ts_0_1", + "name": "fib(20)", + "rank": 2, + "sampleCount": 88, + "totalTime": 512.0, + "min": 1.6, + "max": 3.0, + "hz": 500.0, + "period": 2.0, + "samples": [], + "mean": 2.0, + "variance": 0.25, + "sd": 0.5, + "sem": 0.0533, + "df": 87, + "critical": 1.988, + "moe": 0.106, + "rme": 25.0, + "p75": 2.1, + "p99": 2.8, + "p995": 2.9, + "p999": 3.0, + "median": 1.5 + } + ] + } + ] + }, + { + "filepath": "/home/runner/project/sort.bench.ts", + "groups": [ + { + "fullName": "sort.bench.ts > sorting", + "benchmarks": [ + { + "id": "sort.bench.ts_0_0", + "name": "normal", + "rank": 1, + "sampleCount": 70, + "totalTime": 525.0, + "min": 4.0, + "max": 7.5, + "hz": 200.0, + "period": 5.0, + "samples": [], + "mean": 5.0, + "variance": 1.5625, + "sd": 1.25, + "sem": 0.149, + "df": 69, + "critical": 1.995, + "moe": 0.298, + "rme": 25.0, + "p75": 5.2, + "p99": 7.0, + "p995": 7.3, + "p999": 7.5, + "median": 4.0 + }, + { + "id": "sort.bench.ts_0_1", + "name": "reverse", + "rank": 2, + "sampleCount": 64, + "totalTime": 640.0, + "min": 8.0, + "max": 15.0, + "hz": 100.0, + "period": 10.0, + "samples": [], + "mean": 10.0, + "variance": 6.25, + "sd": 2.5, + "sem": 0.3125, + "df": 63, + "critical": 1.998, + "moe": 0.625, + "rme": 25.0, + "p75": 10.5, + "p99": 14.0, + "p995": 14.5, + "p999": 15.0, + "median": 8.0 + } + ] + } + ] + } + ] +} diff --git a/lib/bencher_adapter/tool_output/js/vitest/two.json b/lib/bencher_adapter/tool_output/js/vitest/two.json new file mode 100644 index 0000000000..6098c7ab75 --- /dev/null +++ b/lib/bencher_adapter/tool_output/js/vitest/two.json @@ -0,0 +1,64 @@ +{ + "files": [ + { + "filepath": "/home/runner/project/math.bench.ts", + "groups": [ + { + "fullName": "math.bench.ts > math", + "benchmarks": [ + { + "id": "math_0_0", + "name": "add", + "rank": 1, + "sampleCount": 99, + "totalTime": 99.0, + "min": 0.8, + "max": 1.5, + "hz": 1000.0, + "period": 1.0, + "samples": [], + "mean": 1.0, + "variance": 0.0625, + "sd": 0.25, + "sem": 0.0251, + "df": 98, + "critical": 1.984, + "moe": 0.0498, + "rme": 25.0, + "p75": 1.05, + "p99": 1.4, + "p995": 1.45, + "p999": 1.5, + "median": 0.75 + }, + { + "id": "math_0_1", + "name": "subtract", + "rank": 2, + "sampleCount": 95, + "totalTime": 190.0, + "min": 1.6, + "max": 3.0, + "hz": 500.0, + "period": 2.0, + "samples": [], + "mean": 2.0, + "variance": 0.25, + "sd": 0.5, + "sem": 0.0513, + "df": 94, + "critical": 1.986, + "moe": 0.102, + "rme": 25.0, + "p75": 2.1, + "p99": 2.8, + "p995": 2.9, + "p999": 3.0, + "median": 1.5 + } + ] + } + ] + } + ] +} diff --git a/lib/bencher_json/src/project/report.rs b/lib/bencher_json/src/project/report.rs index f1950abfd8..869e244dc6 100644 --- a/lib/bencher_json/src/project/report.rs +++ b/lib/bencher_json/src/project/report.rs @@ -102,6 +102,7 @@ const C_SHARP_DOT_NET_INT: i32 = 61; const JS_INT: i32 = 70; const JS_BENCHMARK_INT: i32 = 71; const JS_TIME_INT: i32 = 72; +const JS_VITEST_INT: i32 = 73; const PYTHON_INT: i32 = 80; const PYTHON_ASV_INT: i32 = 81; const PYTHON_PYTEST_INT: i32 = 82; @@ -143,6 +144,7 @@ pub enum Adapter { Js = JS_INT, JsBenchmark = JS_BENCHMARK_INT, JsTime = JS_TIME_INT, + JsVitest = JS_VITEST_INT, Python = PYTHON_INT, PythonAsv = PYTHON_ASV_INT, PythonPytest = PYTHON_PYTEST_INT, @@ -184,6 +186,7 @@ impl Adapter { | Self::CSharpDotNet | Self::JsBenchmark | Self::JsTime + | Self::JsVitest | Self::PythonAsv | Self::PythonPytest | Self::RubyBenchmark @@ -215,6 +218,7 @@ impl fmt::Display for Adapter { Self::Js => write!(f, "js"), Self::JsBenchmark => write!(f, "js_benchmark"), Self::JsTime => write!(f, "js_time"), + Self::JsVitest => write!(f, "js_vitest"), Self::Python => write!(f, "python"), Self::PythonAsv => write!(f, "python_asv"), Self::PythonPytest => write!(f, "python_pytest"), @@ -233,9 +237,10 @@ mod adapter { use super::{ Adapter, C_SHARP_DOT_NET_INT, C_SHARP_INT, CPP_CATCH2_INT, CPP_GOOGLE_INT, CPP_INT, DART_BENCHMARK_HARNESS_INT, DART_INT, GO_BENCH_INT, GO_INT, JAVA_INT, JAVA_JMH_INT, - JS_BENCHMARK_INT, JS_INT, JS_TIME_INT, JSON_INT, MAGIC_INT, PYTHON_ASV_INT, PYTHON_INT, - PYTHON_PYTEST_INT, RUBY_BENCHMARK_INT, RUBY_INT, RUST_BENCH_INT, RUST_CRITERION_INT, - RUST_GUNGRAUN_INT, RUST_IAI_INT, RUST_INT, SHELL_HYPERFINE_INT, SHELL_INT, + JS_BENCHMARK_INT, JS_INT, JS_TIME_INT, JS_VITEST_INT, JSON_INT, MAGIC_INT, PYTHON_ASV_INT, + PYTHON_INT, PYTHON_PYTEST_INT, RUBY_BENCHMARK_INT, RUBY_INT, RUST_BENCH_INT, + RUST_CRITERION_INT, RUST_GUNGRAUN_INT, RUST_IAI_INT, RUST_INT, SHELL_HYPERFINE_INT, + SHELL_INT, }; #[derive(Debug, thiserror::Error)] @@ -273,6 +278,7 @@ mod adapter { Self::Js => JS_INT.to_sql(out), Self::JsBenchmark => JS_BENCHMARK_INT.to_sql(out), Self::JsTime => JS_TIME_INT.to_sql(out), + Self::JsVitest => JS_VITEST_INT.to_sql(out), Self::Python => PYTHON_INT.to_sql(out), Self::PythonAsv => PYTHON_ASV_INT.to_sql(out), Self::PythonPytest => PYTHON_PYTEST_INT.to_sql(out), @@ -312,6 +318,7 @@ mod adapter { JS_INT => Ok(Self::Js), JS_BENCHMARK_INT => Ok(Self::JsBenchmark), JS_TIME_INT => Ok(Self::JsTime), + JS_VITEST_INT => Ok(Self::JsVitest), PYTHON_INT => Ok(Self::Python), PYTHON_ASV_INT => Ok(Self::PythonAsv), PYTHON_PYTEST_INT => Ok(Self::PythonPytest), diff --git a/services/api/openapi.json b/services/api/openapi.json index 91791d5ac0..b34a6ca22f 100644 --- a/services/api/openapi.json +++ b/services/api/openapi.json @@ -11757,6 +11757,7 @@ "js", "js_benchmark", "js_time", + "js_vitest", "python", "python_asv", "python_pytest", diff --git a/services/cli/src/bencher/sub/project/report/create/adapter.rs b/services/cli/src/bencher/sub/project/report/create/adapter.rs index 379adb25a7..ab980dd02c 100644 --- a/services/cli/src/bencher/sub/project/report/create/adapter.rs +++ b/services/cli/src/bencher/sub/project/report/create/adapter.rs @@ -15,6 +15,7 @@ impl From for Adapter { CliReportAdapter::JavaJmh => Self::JavaJmh, CliReportAdapter::JsBenchmark => Self::JsBenchmark, CliReportAdapter::JsTime => Self::JsTime, + CliReportAdapter::JsVitest => Self::JsVitest, CliReportAdapter::PythonAsv => Self::PythonAsv, CliReportAdapter::PythonPytest => Self::PythonPytest, CliReportAdapter::RubyBenchmark => Self::RubyBenchmark, diff --git a/services/cli/src/parser/project/report.rs b/services/cli/src/parser/project/report.rs index 364f5c34f5..17f92ed526 100644 --- a/services/cli/src/parser/project/report.rs +++ b/services/cli/src/parser/project/report.rs @@ -180,6 +180,8 @@ pub enum CliReportAdapter { JsBenchmark, /// 🕸 JavaScript Time JsTime, + /// 🕸 JavaScript Vitest + JsVitest, /// 🐍 Python ASV PythonAsv, /// 🐍 Python Pytest diff --git a/services/console/src/chunks/docs-explanation/adapters/de/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/de/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/de/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/de/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/de/magic.mdx index 99668d8c57..9478abc173 100644 --- a/services/console/src/chunks/docs-explanation/adapters/de/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/de/magic.mdx @@ -15,6 +15,7 @@ Für beste Ergebnisse sollten Sie einen Benchmark-Harness-Adapter angeben: - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/en/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/en/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/en/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/en/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/en/magic.mdx index 57cc58a45b..28b797dfc1 100644 --- a/services/console/src/chunks/docs-explanation/adapters/en/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/en/magic.mdx @@ -15,6 +15,7 @@ For best results, you should specify a benchmark harness adapter: - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/es/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/es/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/es/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/es/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/es/magic.mdx index 5083930143..accaea5623 100644 --- a/services/console/src/chunks/docs-explanation/adapters/es/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/es/magic.mdx @@ -15,6 +15,7 @@ Para obtener mejores resultados, deberías especificar un adaptador de arnés de - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/fr/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/fr/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/fr/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/fr/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/fr/magic.mdx index 5e01743e9f..d3d1dc4cbd 100644 --- a/services/console/src/chunks/docs-explanation/adapters/fr/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/fr/magic.mdx @@ -15,6 +15,7 @@ Pour de meilleurs résultats, vous devriez spécifier un adaptateur pour le fram - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/ja/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/ja/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/ja/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/ja/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/ja/magic.mdx index adf3cb6aaa..7b0a1a7e47 100644 --- a/services/console/src/chunks/docs-explanation/adapters/ja/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/ja/magic.mdx @@ -15,6 +15,7 @@ Magic アダプター(`magic`)は他のすべてのアダプターのスー - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/ko/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/ko/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/ko/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/ko/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/ko/magic.mdx index 064f8d3948..e807397d5b 100644 --- a/services/console/src/chunks/docs-explanation/adapters/ko/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/ko/magic.mdx @@ -15,6 +15,7 @@ - [☕️ Java 마이크로벤치마크 하네스 (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/node-js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/node-js-vitest.mdx new file mode 100644 index 0000000000..17e4ada1e0 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/node-js-vitest.mdx @@ -0,0 +1,3 @@ +```sh +bencher run --adapter js_vitest --file results.json "vitest bench --run --outputJson results.json" +``` diff --git a/services/console/src/chunks/docs-explanation/adapters/pt/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/pt/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/pt/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/pt/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/pt/magic.mdx index 44e9f9228c..7352a38ea5 100644 --- a/services/console/src/chunks/docs-explanation/adapters/pt/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/pt/magic.mdx @@ -15,6 +15,7 @@ Para melhores resultados, você deve especificar um adaptador de harness de benc - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/ru/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/ru/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/ru/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/ru/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/ru/magic.mdx index 64c99e2ba4..a3d286bd17 100644 --- a/services/console/src/chunks/docs-explanation/adapters/ru/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/ru/magic.mdx @@ -15,6 +15,7 @@ - [☕️ Java Microbenchmark Harness (JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-explanation/adapters/zh/js-vitest.mdx b/services/console/src/chunks/docs-explanation/adapters/zh/js-vitest.mdx new file mode 100644 index 0000000000..f33b7382a5 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/adapters/zh/js-vitest.mdx @@ -0,0 +1,16 @@ +import NodeJsVitest from "../node-js-vitest.mdx"; + +## 🕸 JavaScript Vitest + +The JavaScript Vitest Adapter (`js_vitest`) expects [Vitest `bench`](https://vitest.dev/api/#bench) output in JSON format (ie `--outputJson results.json`). +This JSON output is saved to a file, so you must use the `bencher run` CLI `--file` option to specify that file path. +Both the `latency` Measure (ie `nanoseconds (ns)`) and the `throughput` Measure (ie `operations / second (ops/sec)`) are gathered. +For the `throughput` Measure, the `lower_value` and `upper_value` are the relative margin of error below and above the `value` respectively. + + + +There are two options for the `latency` Metric: +- `mean` (default): The `lower_value` and `upper_value` are one standard deviation below and above the mean (ie `value`) respectively. +- `median`: Only the median (ie `value`) is available. Neither `lower_value` nor `upper_value` are collected, as Vitest does not provide an interquartile range. + +This can be specified in the bencher run CLI subcommand with the `--average` option. diff --git a/services/console/src/chunks/docs-explanation/adapters/zh/magic.mdx b/services/console/src/chunks/docs-explanation/adapters/zh/magic.mdx index 663ffff380..ebd85ff3a4 100644 --- a/services/console/src/chunks/docs-explanation/adapters/zh/magic.mdx +++ b/services/console/src/chunks/docs-explanation/adapters/zh/magic.mdx @@ -15,6 +15,7 @@ - [☕️ Java 微基准测试套件(JMH)](#%EF%B8%8F-java-jmh) - [🕸 JavaScript Benchmark.js](#-javascript-benchmark) - [🕸 JavaScript console.time/console.timeEnd](#-javascript-time) +- [🕸 JavaScript Vitest](#-javascript-vitest) - [🐍 Python airspeed velocity (asv)](#-python-asv) - [🐍 Python pytest-benchmark](#-python-pytest) - [♦️ Ruby Benchmark](#%EF%B8%8F-ruby-benchmark) diff --git a/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx b/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx index af30bc38da..3b772aa68a 100644 --- a/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx +++ b/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx @@ -1,3 +1,6 @@ +## Pending +- Add Vitest adapter (`js_vitest`) + ## `v0.6.7` - Fix the OCI registry token endpoint for the Docker 29+ containerd image store, which sends multiple `scope` query parameters and an `OAuth2` POST token exchange (Thank you [@travishathaway](https://github.com/travishathaway)) - Add user-scoped API keys (`bencher_user_...`) that authenticate as the owning user across every endpoint a JWT can reach, including `docker login`; the one exception is key management: a user API key cannot create more keys and can only see, update, or revoke itself, so a leaked key cannot mint credentials that outlive its own revocation, tamper with the user's other keys, or enumerate them diff --git a/services/console/src/components/adapter/BencherRun.astro b/services/console/src/components/adapter/BencherRun.astro index ae4d6f37d7..aa45d103c1 100644 --- a/services/console/src/components/adapter/BencherRun.astro +++ b/services/console/src/components/adapter/BencherRun.astro @@ -129,6 +129,16 @@ const { isConsole } = Astro.props; lang="powershell" code={adapterCommand(isConsole, Adapter.JsTime)} /> + + { {props.js_time_bash} + + + {props.js_vitest_bash} + + {props.python_asv_bash} diff --git a/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx b/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx index 5edeb4fcb6..e56387d204 100644 --- a/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx +++ b/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx @@ -33,7 +33,7 @@ const BenchmarkHarnessFallback = () => (
diff --git a/services/console/src/components/adapter/BenchmarkHarnessInner.tsx b/services/console/src/components/adapter/BenchmarkHarnessInner.tsx index 477dacfb16..f798c3c72b 100644 --- a/services/console/src/components/adapter/BenchmarkHarnessInner.tsx +++ b/services/console/src/components/adapter/BenchmarkHarnessInner.tsx @@ -36,7 +36,7 @@ const BenchmarkHarnessInner = () => (
diff --git a/services/console/src/components/adapter/adapter.ts b/services/console/src/components/adapter/adapter.ts index 338774d0b5..fe533b9647 100644 --- a/services/console/src/components/adapter/adapter.ts +++ b/services/console/src/components/adapter/adapter.ts @@ -39,6 +39,7 @@ export const adapterIcon = (adapter: Adapter) => { return C_SHARP_ICON; case Adapter.JsBenchmark: case Adapter.JsTime: + case Adapter.JsVitest: return JS_ICON; case Adapter.PythonAsv: case Adapter.PythonPytest: @@ -78,6 +79,8 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { case Adapter.JsBenchmark: case Adapter.JsTime: return `bencher run${host} "node benchmark.js"`; + case Adapter.JsVitest: + return `bencher run${host} --file results.json "vitest bench --run --outputJson results.json"`; case Adapter.PythonAsv: return `bencher run${host} "asv run"`; case Adapter.PythonPytest: @@ -160,6 +163,7 @@ const validAdapter = (adapter: undefined | null | string | Adapter) => { case Adapter.CSharpDotNet: case Adapter.JsBenchmark: case Adapter.JsTime: + case Adapter.JsVitest: case Adapter.PythonAsv: case Adapter.PythonPytest: case Adapter.RubyBenchmark: diff --git a/services/console/src/components/adapter/name.ts b/services/console/src/components/adapter/name.ts index ed5f65f7d2..9aa12f44f5 100644 --- a/services/console/src/components/adapter/name.ts +++ b/services/console/src/components/adapter/name.ts @@ -30,6 +30,8 @@ export const adapterName = (adapter: Adapter): string => { return "Benchmark.js"; case Adapter.JsTime: return "console.time/console.timeEnd"; + case Adapter.JsVitest: + return "Vitest"; case Adapter.PythonAsv: return "airspeed velocity"; case Adapter.PythonPytest: @@ -66,6 +68,8 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { case Adapter.JsBenchmark: case Adapter.JsTime: return `bencher run${host} "node benchmark.js"`; + case Adapter.JsVitest: + return `bencher run${host} --file results.json "vitest bench --run --outputJson results.json"`; case Adapter.PythonAsv: return `bencher run${host} "asv run"`; case Adapter.PythonPytest: diff --git a/services/console/src/components/console/deck/hand/card/ViewCard.tsx b/services/console/src/components/console/deck/hand/card/ViewCard.tsx index b2c1e402e6..3db31e72bf 100644 --- a/services/console/src/components/console/deck/hand/card/ViewCard.tsx +++ b/services/console/src/components/console/deck/hand/card/ViewCard.tsx @@ -443,6 +443,8 @@ const AdapterCard = (props: Props) => { return "-javascript-benchmark"; case Adapter.JsTime: return "-javascript-time"; + case Adapter.JsVitest: + return "-javascript-vitest"; case Adapter.PythonAsv: return "-python-asv"; case Adapter.PythonPytest: @@ -490,6 +492,8 @@ const AdapterCard = (props: Props) => { return "JavaScript Benchmark.js"; case Adapter.JsTime: return "JavaScript console.time/console.timeEnd"; + case Adapter.JsVitest: + return "JavaScript Vitest"; case Adapter.PythonAsv: return "Python airspeed velocity (asv)"; case Adapter.PythonPytest: diff --git a/services/console/src/components/landing/Harnesses.astro b/services/console/src/components/landing/Harnesses.astro index a9d1b24148..f7eccf5ee1 100644 --- a/services/console/src/components/landing/Harnesses.astro +++ b/services/console/src/components/landing/Harnesses.astro @@ -8,7 +8,7 @@ const groups = [ { language: "Python", harnesses: ["pytest-benchmark", "airspeed velocity"] }, { language: "Java", harnesses: ["JMH"] }, { language: "C#", harnesses: ["BenchmarkDotNet"] }, - { language: "JavaScript", harnesses: ["Benchmark.js"] }, + { language: "JavaScript", harnesses: ["Benchmark.js", "Vitest"] }, { language: "Go", harnesses: ["go test -bench"] }, { language: "Ruby", harnesses: ["Benchmark"] }, { language: "Dart", harnesses: ["benchmark_harness"] }, diff --git a/services/console/src/content/docs-explanation/de/adapters.mdx b/services/console/src/content/docs-explanation/de/adapters.mdx index b3c5aa0965..eb95d2a268 100644 --- a/services/console/src/content/docs-explanation/de/adapters.mdx +++ b/services/console/src/content/docs-explanation/de/adapters.mdx @@ -3,7 +3,7 @@ title: "Benchmark-Adapter" description: "Verwenden Sie Ihren bevorzugten Code-Benchmark-Harness mit den eingebauten Adaptern von Bencher oder verwenden Sie einen benutzerdefinierten Code-Benchmark-Harness, der JSON ausgibt" heading: "Benchmark-Harness-Adapter" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/de/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/de/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/de/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/de/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/de/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/de/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/de/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/de/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/de/shell-h
+
diff --git a/services/console/src/content/docs-explanation/en/adapters.mdx b/services/console/src/content/docs-explanation/en/adapters.mdx index 4413b8fcb6..ef5d00980f 100644 --- a/services/console/src/content/docs-explanation/en/adapters.mdx +++ b/services/console/src/content/docs-explanation/en/adapters.mdx @@ -3,7 +3,7 @@ title: "Benchmark Adapters" description: "Use your favorite code benchmark harness with Bencher's built-in adapters or use a custom code benchmark harness that outputs JSON" heading: "Benchmark Harness Adapters" published: "2023-08-12T16:07:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/en/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/en/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/en/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/en/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/en/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/en/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/en/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/en/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/en/shell-h
+
diff --git a/services/console/src/content/docs-explanation/es/adapters.mdx b/services/console/src/content/docs-explanation/es/adapters.mdx index bb730f53ab..4acf9cf246 100644 --- a/services/console/src/content/docs-explanation/es/adapters.mdx +++ b/services/console/src/content/docs-explanation/es/adapters.mdx @@ -3,7 +3,7 @@ title: "Adaptadores de referencia" description: "Utilice su arnés de referencia de código favorito con los adaptadores incorporados en Bencher o utilice un arnés de referencia de código personalizado que genere JSON." heading: "Adaptadores de Arnés de Referencia" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/es/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/es/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/es/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/es/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/es/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/es/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/es/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/es/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/es/shell-h
+
diff --git a/services/console/src/content/docs-explanation/fr/adapters.mdx b/services/console/src/content/docs-explanation/fr/adapters.mdx index 24acb5ce73..63d6a84723 100644 --- a/services/console/src/content/docs-explanation/fr/adapters.mdx +++ b/services/console/src/content/docs-explanation/fr/adapters.mdx @@ -3,7 +3,7 @@ title: "Adaptateurs de Benchmark" description: "Utilisez votre harnais de benchmark de code préféré avec les adaptateurs intégrés de Bencher ou utilisez un harnais de benchmark de code personnalisé qui produit du JSON" heading: "Adaptateurs de Harnais de Benchmark" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/fr/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/fr/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/fr/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/fr/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/fr/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/fr/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/fr/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/fr/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/fr/shell-h
+
diff --git a/services/console/src/content/docs-explanation/ja/adapters.mdx b/services/console/src/content/docs-explanation/ja/adapters.mdx index 6afcfccc50..3e32523eff 100644 --- a/services/console/src/content/docs-explanation/ja/adapters.mdx +++ b/services/console/src/content/docs-explanation/ja/adapters.mdx @@ -3,7 +3,7 @@ title: "ベンチマークアダプター" description: "お気に入りのコードベンチマークハーネスをBencherの内蔵アダプターと組み合わせるか、JSONを出力するカスタムコードベンチマークハーネスを使用してください" heading: "ベンチマークハーネスアダプター" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/ja/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/ja/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/ja/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/ja/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/ja/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/ja/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/ja/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/ja/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/ja/shell-h
+
diff --git a/services/console/src/content/docs-explanation/ko/adapters.mdx b/services/console/src/content/docs-explanation/ko/adapters.mdx index 1d76ead308..70a22b8f15 100644 --- a/services/console/src/content/docs-explanation/ko/adapters.mdx +++ b/services/console/src/content/docs-explanation/ko/adapters.mdx @@ -3,7 +3,7 @@ title: "벤치마크 어댑터" description: "Bencher의 기본 어댑터를 사용하여 좋아하는 코드 벤치마크 하네스를 사용하거나, JSON을 출력하는 사용자 정의 코드 벤치마크 하네스를 사용하세요." heading: "벤치마크 하네스 어댑터" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/ko/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/ko/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/ko/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/ko/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/ko/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/ko/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/ko/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/ko/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/ko/shell-h
+
diff --git a/services/console/src/content/docs-explanation/pt/adapters.mdx b/services/console/src/content/docs-explanation/pt/adapters.mdx index e50f787f74..b00b9d958f 100644 --- a/services/console/src/content/docs-explanation/pt/adapters.mdx +++ b/services/console/src/content/docs-explanation/pt/adapters.mdx @@ -3,7 +3,7 @@ title: "Adaptadores de Benchmark" description: "Use sua ferramenta de benchmark de código preferida com os adaptadores integrados do Bencher ou use uma ferramenta de benchmark de código personalizada que gera JSON" heading: "Adaptadores de Ferramenta de Benchmark" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/pt/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/pt/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/pt/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/pt/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/pt/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/pt/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/pt/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/pt/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/pt/shell-h
+
diff --git a/services/console/src/content/docs-explanation/ru/adapters.mdx b/services/console/src/content/docs-explanation/ru/adapters.mdx index 002fd193f9..e06811d246 100644 --- a/services/console/src/content/docs-explanation/ru/adapters.mdx +++ b/services/console/src/content/docs-explanation/ru/adapters.mdx @@ -3,7 +3,7 @@ title: "Адаптеры для тестирования производите description: "Используйте свой любимый профилировщик кода с встроенными адаптерами Bencher или создайте собственный профилировщик, который выводит данные в формате JSON" heading: "Адаптеры для профилировщиков" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/ru/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/ru/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/ru/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/ru/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/ru/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/ru/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/ru/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/ru/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/ru/shell-h
+
diff --git a/services/console/src/content/docs-explanation/zh/adapters.mdx b/services/console/src/content/docs-explanation/zh/adapters.mdx index 5a80f3dc25..2f1940a6c2 100644 --- a/services/console/src/content/docs-explanation/zh/adapters.mdx +++ b/services/console/src/content/docs-explanation/zh/adapters.mdx @@ -3,7 +3,7 @@ title: "基准测试适配器" description: "使用Bencher的内置适配器和你最喜欢的代码基准测试程序,或者使用输出JSON的自定义代码基准测试程序" heading: "基准测试程序适配器" published: "2023-10-27T08:40:00Z" -modified: "2025-10-12T17:17:00Z" +modified: "2026-06-05T08:00:00Z" sortOrder: 8 --- @@ -20,6 +20,7 @@ import GoBench from "../../../chunks/docs-explanation/adapters/zh/go-bench.mdx"; import JavaJmh from "../../../chunks/docs-explanation/adapters/zh/java-jmh.mdx"; import JsBenchmark from "../../../chunks/docs-explanation/adapters/zh/js-benchmark.mdx"; import JsTime from "../../../chunks/docs-explanation/adapters/zh/js-time.mdx"; +import JsVitest from "../../../chunks/docs-explanation/adapters/zh/js-vitest.mdx"; import PythonAsv from "../../../chunks/docs-explanation/adapters/zh/python-asv.mdx"; import PythonPytest from "../../../chunks/docs-explanation/adapters/zh/python-pytest.mdx"; import RubyBenchmark from "../../../chunks/docs-explanation/adapters/zh/ruby-benchmark.mdx"; @@ -50,6 +51,7 @@ import ShellHyperfine from "../../../chunks/docs-explanation/adapters/zh/shell-h
+
diff --git a/services/console/src/types/bencher.ts b/services/console/src/types/bencher.ts index a698c2f176..310096ab1a 100644 --- a/services/console/src/types/bencher.ts +++ b/services/console/src/types/bencher.ts @@ -1007,6 +1007,7 @@ export enum Adapter { Js = "js", JsBenchmark = "js_benchmark", JsTime = "js_time", + JsVitest = "js_vitest", Python = "python", PythonAsv = "python_asv", PythonPytest = "python_pytest",