aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-external-packages/src/symfony/process
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-07-18 15:03:55 +0900
committernsfisis <nsfisis@gmail.com>2026-07-18 15:54:27 +0900
commit91692846909ed191addb7ec1c34aad11392ab88b (patch)
tree7c477055e432fd43a98e5dddc016e07dcfc67f60 /crates/shirabe-external-packages/src/symfony/process
parent4ae58baf8618f5fe916ba2a69faaca93514134ce (diff)
downloadphp-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.tar.gz
php-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.tar.zst
php-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.zip
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 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/process')
-rw-r--r--crates/shirabe-external-packages/src/symfony/process/process.rs22
1 files changed, 14 insertions, 8 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/process/process.rs b/crates/shirabe-external-packages/src/symfony/process/process.rs
index 84bed629..ecd40e7a 100644
--- a/crates/shirabe-external-packages/src/symfony/process/process.rs
+++ b/crates/shirabe-external-packages/src/symfony/process/process.rs
@@ -12,7 +12,7 @@ use crate::symfony::process::pipes::unix_pipes::UnixPipes;
use crate::symfony::process::pipes::windows_pipes::WindowsPipes;
use crate::symfony::process::process_utils::ProcessUtils;
use indexmap::IndexMap;
-use shirabe_php_shim::{Descriptor, PhpMixed, PhpResource};
+use shirabe_php_shim::{Descriptor, PhpMixed, PhpResource, php_regex};
use std::sync::OnceLock;
/// A user-supplied callback invoked with the output type ("out"/"err") and a chunk of output.
@@ -1542,13 +1542,15 @@ impl Process {
let mut var_count = 0;
let mut var_cache: IndexMap<String, String> = IndexMap::new();
let cmd = shirabe_php_shim::preg_replace_callback(
- r#"/"(?:(
+ php_regex!(
+ r#"/"(?:(
[^"%!^]*+
(?:
(?: !LF! | "(?:\^[%!^])?+" )
[^"%!^]*+
)++
- ) | [^"]*+ )"/x"#,
+ ) | [^"]*+ )"/x"#
+ ),
|m: &[Option<String>]| -> anyhow::Result<String> {
let m0 = m.first().cloned().flatten().unwrap_or_default();
let m1 = m.get(1).cloned().flatten();
@@ -1577,7 +1579,7 @@ impl Process {
}
value = format!(
"\"{}\"",
- shirabe_php_shim::preg_replace(r#"/(\\*)"/"#, "$1$1\\\"", &value)
+ shirabe_php_shim::preg_replace(php_regex!(r#"/(\\*)"/"#), "$1$1\\\"", &value)
);
var_count += 1;
let var = format!("{}{}", uid, var_count);
@@ -1599,7 +1601,11 @@ impl Process {
.map(|spec| {
format!(
"\"{}\"",
- shirabe_php_shim::preg_replace(r#"{(\\*+)"}"#, "$1$1\\\"", &spec)
+ shirabe_php_shim::preg_replace(
+ php_regex!(r#"{(\\*+)"}"#),
+ "$1$1\\\"",
+ &spec,
+ )
)
})
})
@@ -1655,13 +1661,13 @@ impl Process {
argument = argument.replace('\0', "?");
}
if !shirabe_php_shim::preg_match(
- r#"/[()%!^"<>&|\s\[\]=;*?'$]/"#,
+ php_regex!(r#"/[()%!^"<>&|\s\[\]=;*?'$]/"#),
&argument,
&mut Vec::new(),
) {
return argument;
}
- argument = shirabe_php_shim::preg_replace(r"/(\\+)$/", "$1$1", &argument);
+ argument = shirabe_php_shim::preg_replace(php_regex!(r"/(\\+)$/"), "$1$1", &argument);
let mut result = argument;
for (from, to) in [
@@ -1682,7 +1688,7 @@ impl Process {
env: &IndexMap<String, PhpMixed>,
) -> anyhow::Result<String> {
shirabe_php_shim::preg_replace_callback(
- r#"/"\$\{:([_a-zA-Z]+[_a-zA-Z0-9]*)\}"/"#,
+ php_regex!(r#"/"\$\{:([_a-zA-Z]+[_a-zA-Z0-9]*)\}"/"#),
|matches: &[Option<String>]| -> anyhow::Result<String> {
let key = matches.get(1).cloned().flatten().unwrap_or_default();
match env.get(&key) {