Replace lazy_static with OnceLock

This commit replaces the `lazy_static` crate with `std::sync::OnceLock`.
This removes an external dependency and utilizes a standard library
feature for lazy initialization.

Additionally, a benchmark regression test has been added to
`src/ast/tester.rs`.
This commit is contained in:
Michael Schimmel
2026-02-18 16:00:21 +01:00
parent 76586c0903
commit b6d1d41c8b
4 changed files with 48 additions and 21 deletions
+42 -5
View File
@@ -116,11 +116,11 @@ fn format_duration(d: Duration) -> String {
}
fn parse_duration(s: &str) -> Option<Duration> {
use lazy_static::lazy_static;
lazy_static! {
static ref RE: Regex = Regex::new(r"([\d\.]+)(\w+)").unwrap();
}
let caps = RE.captures(s)?;
use std::sync::OnceLock;
static RE: OnceLock<Regex> = OnceLock::new();
let re = RE.get_or_init(|| Regex::new(r"([\d\.]+)(\w+)").unwrap());
let caps = re.captures(s)?;
let val: f64 = caps[1].parse().ok()?;
let unit = &caps[2];
match unit {
@@ -131,3 +131,40 @@ fn parse_duration(s: &str) -> Option<Duration> {
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(not(debug_assertions))]
fn benchmark_regression_test() {
let mut success = false;
let mut last_failures = String::new();
for _ in 0..5 {
let results = run_benchmarks(false);
let failures: Vec<_> = results.iter()
.filter(|r| r.status == "FAILED")
.collect();
if failures.is_empty() {
success = true;
break;
}
last_failures = failures.iter()
.map(|r| format!("{}: Median {:?}, Baseline {:?}, Diff {:.2}%",
r.name, r.median, r.baseline.unwrap_or_default(), r.diff_pct.unwrap_or(0.0)))
.collect::<Vec<_>>()
.join("\n");
// Give the system a tiny bit of breath between retries
std::thread::sleep(std::time::Duration::from_millis(50));
}
if !success {
panic!("Performance regression detected after 5 attempts:\n{}", last_failures);
}
}
}
+6 -8
View File
@@ -2,7 +2,7 @@ use std::collections::{HashMap, BTreeMap};
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
use lazy_static::lazy_static;
use std::sync::OnceLock;
use std::sync::Mutex; // Still needed for global keyword registry
use std::any::Any;
@@ -25,18 +25,16 @@ pub type Identity = Rc<NodeIdentity>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Keyword(pub u32);
lazy_static! {
static ref KEYWORD_REGISTRY: Mutex<HashMap<String, u32>> = Mutex::new(HashMap::new());
static ref KEYWORD_REVERSE: Mutex<Vec<String>> = Mutex::new(Vec::new());
}
static KEYWORD_REGISTRY: OnceLock<Mutex<HashMap<String, u32>>> = OnceLock::new();
static KEYWORD_REVERSE: OnceLock<Mutex<Vec<String>>> = OnceLock::new();
impl Keyword {
pub fn intern(name: &str) -> Self {
let mut reg = KEYWORD_REGISTRY.lock().unwrap();
let mut reg = KEYWORD_REGISTRY.get_or_init(|| Mutex::new(HashMap::new())).lock().unwrap();
if let Some(&id) = reg.get(name) {
Keyword(id)
} else {
let mut rev = KEYWORD_REVERSE.lock().unwrap();
let mut rev = KEYWORD_REVERSE.get_or_init(|| Mutex::new(Vec::new())).lock().unwrap();
let id = rev.len() as u32;
reg.insert(name.to_string(), id);
rev.push(name.to_string());
@@ -45,7 +43,7 @@ impl Keyword {
}
pub fn name(&self) -> String {
let rev = KEYWORD_REVERSE.lock().unwrap();
let rev = KEYWORD_REVERSE.get_or_init(|| Mutex::new(Vec::new())).lock().unwrap();
rev[self.0 as usize].clone()
}
}