From e0d1424c73d3df09347372b8273bd730349c85a6 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sat, 16 Mar 2024 17:26:47 +0800 Subject: [PATCH] replace `once_cell::sync::Lazy` with `std::sync::OnceLock` --- Cargo.toml | 1 - src/criterion.rs | 16 ++++----- src/lib.rs | 88 +++++++++++++++++++++++++++++------------------- src/routine.rs | 2 +- 4 files changed, 62 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9579e5a..d09d123 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ bench = false [dependencies] anes = "0.1.6" -once_cell = "1.19" itertools = "0.12" serde = "1.0" serde_json = "1.0" diff --git a/src/criterion.rs b/src/criterion.rs index d243f49..fa14cd2 100644 --- a/src/criterion.rs +++ b/src/criterion.rs @@ -10,11 +10,11 @@ use regex::Regex; use crate::bencher::Bencher; use crate::benchmark_group::{BenchmarkGroup, BenchmarkId}; use crate::{ - debug_enabled, Baseline, BencherReport, BenchmarkConfig, BenchmarkFilter, CliReport, + cargo_criterion_connection, debug_enabled, default_output_directory, default_plotting_backend, + gnuplot_version, Baseline, BencherReport, BenchmarkConfig, BenchmarkFilter, CliReport, CliVerbosity, Connection, ExternalProfiler, Html, ListFormat, Measurement, Mode, OutgoingMessage, PlotConfiguration, PlottingBackend, Profiler, Report, ReportContext, Reports, - SamplingMode, WallTime, CARGO_CRITERION_CONNECTION, DEFAULT_OUTPUT_DIRECTORY, - DEFAULT_PLOTTING_BACKEND, GNUPLOT_VERSION, + SamplingMode, WallTime, }; /// The benchmark manager @@ -65,7 +65,7 @@ impl Default for Criterion { cli: CliReport::new(false, false, CliVerbosity::Normal), bencher_enabled: false, bencher: BencherReport, - html: DEFAULT_PLOTTING_BACKEND.create_plotter().map(Html::new), + html: default_plotting_backend().create_plotter().map(Html::new), csv_enabled: cfg!(feature = "csv_output"), }; @@ -86,12 +86,12 @@ impl Default for Criterion { baseline_directory: "base".to_owned(), baseline: Baseline::Save, load_baseline: None, - output_directory: DEFAULT_OUTPUT_DIRECTORY.clone(), + output_directory: default_output_directory().clone(), all_directories: HashSet::new(), all_titles: HashSet::new(), measurement: WallTime, profiler: Box::new(RefCell::new(ExternalProfiler)), - connection: CARGO_CRITERION_CONNECTION.as_ref().map(|mtx| mtx.lock().unwrap()), + connection: cargo_criterion_connection().as_ref().map(|mtx| mtx.lock().unwrap()), mode: Mode::Benchmark, }; @@ -143,7 +143,7 @@ impl Criterion { pub fn plotting_backend(mut self, backend: PlottingBackend) -> Criterion { if let PlottingBackend::Gnuplot = backend { assert!( - !GNUPLOT_VERSION.is_err(), + !gnuplot_version().is_err(), "Gnuplot plotting backend was requested, but gnuplot is not available. \ To continue, either install Gnuplot or allow Criterion.rs to fall back \ to using plotters." @@ -297,7 +297,7 @@ impl Criterion { pub fn with_plots(mut self) -> Criterion { // If running under cargo-criterion then don't re-enable the reports; let it do the reporting. if self.connection.is_none() && self.report.html.is_none() { - let default_backend = DEFAULT_PLOTTING_BACKEND.create_plotter(); + let default_backend = default_plotting_backend().create_plotter(); if let Some(backend) = default_backend { self.report.html = Some(Html::new(backend)); } else { diff --git a/src/lib.rs b/src/lib.rs index b30ca4b..84a77cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,10 +78,10 @@ use std::net::TcpStream; use std::path::PathBuf; use std::process::Command; use std::sync::Mutex; +use std::sync::OnceLock; use std::time::Duration; use crate::criterion_plot::{Version, VersionError}; -use once_cell::sync::Lazy; use crate::benchmark::BenchmarkConfig; use crate::connection::Connection; @@ -116,48 +116,66 @@ pub use crate::codspeed::criterion::Criterion; #[cfg(not(feature = "codspeed"))] pub use crate::criterion::Criterion; -static DEBUG_ENABLED: Lazy = Lazy::new(|| std::env::var_os("CRITERION_DEBUG").is_some()); -static GNUPLOT_VERSION: Lazy> = - Lazy::new(crate::criterion_plot::version); -static DEFAULT_PLOTTING_BACKEND: Lazy = Lazy::new(|| match &*GNUPLOT_VERSION { - Ok(_) => PlottingBackend::Gnuplot, - #[cfg(feature = "plotters")] - Err(e) => { - match e { - VersionError::Exec(_) => eprintln!("Gnuplot not found, using plotters backend"), - e => eprintln!("Gnuplot not found or not usable, using plotters backend\n{}", e), - }; - PlottingBackend::Plotters - } - #[cfg(not(feature = "plotters"))] - Err(_) => PlottingBackend::None, -}); -static CARGO_CRITERION_CONNECTION: Lazy>> = - Lazy::new(|| match std::env::var("CARGO_CRITERION_PORT") { +fn gnuplot_version() -> &'static Result { + static GNUPLOT_VERSION: OnceLock> = OnceLock::new(); + + GNUPLOT_VERSION.get_or_init(criterion_plot::version) +} + +fn default_plotting_backend() -> &'static PlottingBackend { + static DEFAULT_PLOTTING_BACKEND: OnceLock = OnceLock::new(); + + DEFAULT_PLOTTING_BACKEND.get_or_init(|| match gnuplot_version() { + Ok(_) => PlottingBackend::Gnuplot, + #[cfg(feature = "plotters")] + Err(e) => { + match e { + VersionError::Exec(_) => eprintln!("Gnuplot not found, using plotters backend"), + e => eprintln!("Gnuplot not found or not usable, using plotters backend\n{}", e), + }; + PlottingBackend::Plotters + } + #[cfg(not(feature = "plotters"))] + Err(_) => PlottingBackend::None, + }) +} + +fn cargo_criterion_connection() -> &'static Option> { + static CARGO_CRITERION_CONNECTION: OnceLock>> = OnceLock::new(); + + CARGO_CRITERION_CONNECTION.get_or_init(|| match std::env::var("CARGO_CRITERION_PORT") { Ok(port_str) => { let port: u16 = port_str.parse().ok()?; let stream = TcpStream::connect(("localhost", port)).ok()?; Some(Mutex::new(Connection::new(stream).ok()?)) } Err(_) => None, - }); -static DEFAULT_OUTPUT_DIRECTORY: Lazy = Lazy::new(|| { - // Set criterion home to (in descending order of preference): - // - $CRITERION_HOME (cargo-criterion sets this, but other users could as well) - // - $CARGO_TARGET_DIR/criterion - // - the cargo target dir from `cargo metadata` - // - ./target/criterion - if let Some(value) = env::var_os("CRITERION_HOME") { - PathBuf::from(value) - } else if let Some(path) = cargo_target_directory() { - path.join("criterion") - } else { - PathBuf::from("target/criterion") - } -}); + }) +} + +fn default_output_directory() -> &'static PathBuf { + static DEFAULT_OUTPUT_DIRECTORY: OnceLock = OnceLock::new(); + + DEFAULT_OUTPUT_DIRECTORY.get_or_init(|| { + // Set criterion home to (in descending order of preference): + // - $CRITERION_HOME (cargo-criterion sets this, but other users could as well) + // - $CARGO_TARGET_DIR/criterion + // - the cargo target dir from `cargo metadata` + // - ./target/criterion + if let Some(value) = env::var_os("CRITERION_HOME") { + PathBuf::from(value) + } else if let Some(path) = cargo_target_directory() { + path.join("criterion") + } else { + PathBuf::from("target/criterion") + } + }) +} fn debug_enabled() -> bool { - *DEBUG_ENABLED + static DEBUG_ENABLED: OnceLock = OnceLock::new(); + + *DEBUG_ENABLED.get_or_init(|| std::env::var_os("CRITERION_DEBUG").is_some()) } /// A function that is opaque to the optimizer, used to prevent the compiler from diff --git a/src/routine.rs b/src/routine.rs index 3ed992c..0605585 100644 --- a/src/routine.rs +++ b/src/routine.rs @@ -38,7 +38,7 @@ pub(crate) trait Routine { criterion.report.profile(id, report_context, time.as_nanos() as f64); let mut profile_path = report_context.output_directory.clone(); - if (*crate::CARGO_CRITERION_CONNECTION).is_some() { + if (*crate::cargo_criterion_connection()).is_some() { // If connected to cargo-criterion, generate a cargo-criterion-style path. // This is kind of a hack. profile_path.push("profile");