From 91692846909ed191addb7ec1c34aad11392ab88b Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 18 Jul 2026 15:03:55 +0900 Subject: perf(regex): eliminate per-call clone overhead in preg_* dispatch regex::Regex::clone() does not share the underlying meta engine's search-cache pool, so every fresh clone pays a ~10us warmup cost on its first use. Two changes together eliminate this across nearly all preg_* call sites: - A php_regex! macro resolves PHP-style patterns to a per-call-site &'static regex::Regex (via regex-macro's LazyLock), applied at the majority of call sites throughout the codebase. - Call sites still passing dynamic pattern strings go through PATTERN_CACHE, which now stores Arc<(Regex, bool)> and hands out Arc::clone()s instead of cloning the Regex itself. PregPattern::resolve() returns a ResolvedPattern enum (Arc or 'static reference) rather than an owned Regex, so neither path ever clones the Regex proper. Co-Authored-By: Claude Sonnet 5 --- crates/shirabe/src/util/http_downloader.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'crates/shirabe/src/util/http_downloader.rs') diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs index 98678ad2..b055a515 100644 --- a/crates/shirabe/src/util/http_downloader.rs +++ b/crates/shirabe/src/util/http_downloader.rs @@ -19,8 +19,8 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::{CaptureKey, Preg}; use shirabe_php_shim::{ InvalidArgumentException, LogicException, PhpMixed, array_replace_recursive, chr, - extension_loaded, file_get_contents, function_exists, implode, is_numeric, rawurldecode, - stream_context_create, stripos, strpos, substr, ucfirst, + extension_loaded, file_get_contents, function_exists, implode, is_numeric, php_regex, + rawurldecode, stream_context_create, stripos, strpos, substr, ucfirst, }; use shirabe_semver::constraint::SimpleConstraint; @@ -253,7 +253,11 @@ impl HttpDownloader { // capture username/password from URL if there is one let mut m: IndexMap = IndexMap::new(); - if Preg::is_match3(r"{^https?://([^:/]+):([^@/]+)@([^/]+)}i", url, Some(&mut m)) { + if Preg::is_match3( + php_regex!(r"{^https?://([^:/]+):([^@/]+)@([^/]+)}i"), + url, + Some(&mut m), + ) { self.io.borrow_mut().set_authentication( origin.clone(), rawurldecode( @@ -378,7 +382,7 @@ impl HttpDownloader { let clean_message = |msg: &str| -> anyhow::Result { if !io.is_decorated() { return Ok(Preg::replace( - &format!("{{{}{}}}u", chr(27), "\\[[;\\d]*m"), + format!("{{{}{}}}u", chr(27), "\\[[;\\d]*m"), "", msg, )); @@ -515,7 +519,7 @@ impl HttpDownloader { return false; } - if !Preg::is_match(r"{^https?://}i", url) { + if !Preg::is_match(php_regex!(r"{^https?://}i"), url) { return false; } -- cgit v1.3.1