From a904bb3f032a702e279813cdc451b830a62969a1 Mon Sep 17 00:00:00 2001 From: nibon7 Date: Sat, 27 Jul 2024 15:54:06 +0800 Subject: [PATCH] Replace once_cell::sync::Lazy with std::sync::OnceLock (#757) --- Cargo.toml | 1 - src/lib.rs | 103 +++++++++++++++++++++++++++++-------------------- src/routine.rs | 2 +- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 42a3f87b..62dd2a1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ exclude = ["book/*"] [dependencies] anes = "0.1.4" -once_cell = "1.14" criterion-plot = { path = "plot", version = "0.5.0" } itertools = "0.13" serde = { version = "1.0", features = ["derive"] } diff --git a/src/lib.rs b/src/lib.rs index dd8d9f67..8b5a30f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,7 +74,7 @@ use std::sync::{Mutex, MutexGuard}; use std::time::Duration; use criterion_plot::{Version, VersionError}; -use once_cell::sync::Lazy; +use std::sync::OnceLock; use crate::benchmark::BenchmarkConfig; use crate::connection::Connection; @@ -92,50 +92,69 @@ pub use crate::bencher::AsyncBencher; pub use crate::bencher::Bencher; pub use crate::benchmark_group::{BenchmarkGroup, BenchmarkId}; -static DEBUG_ENABLED: Lazy = Lazy::new(|| std::env::var_os("CRITERION_DEBUG").is_some()); -static GNUPLOT_VERSION: Lazy> = Lazy::new(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 @@ -392,7 +411,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"), }; @@ -413,12 +432,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 + connection: cargo_criterion_connection() .as_ref() .map(|mtx| mtx.lock().unwrap()), mode: Mode::Benchmark, @@ -477,7 +496,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." @@ -631,7 +650,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/routine.rs b/src/routine.rs index 949fb338..c89e406f 100644 --- a/src/routine.rs +++ b/src/routine.rs @@ -38,7 +38,7 @@ pub(crate) trait Routine { .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");