You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Performance of preg_match varies depending on how subject string is initialized #24380
Execution time A: […]
Execution time A: 0.052051 sec.
Execution time B: 0.054563 sec.
Execution time C: 0.052694 sec.
Execution time D: 0.030555 sec.
Execution time A: 0.052350 sec.
Execution time B: 0.052309 sec.
Execution time C: 0.052223 sec.
Execution time D: 0.030175 sec.
But I expected this output instead:
All execution times should nearly be identical.
$textD is somehow fastest for PHP 8.4 and 8.5
$textB and $textD are fastest for PHP 8.2 and PHP 8.3
This is expected. With /u, preg_match() checks that the subject is valid UTF-8, then marks the string so later calls skip the check, but it can't mark interned strings (php_pcre.c). Only D is built at runtime; A and C are compile-time literals, and so is B since 8.4 (#14546).
Indeed, depending on how something is compiled or how something is initialized, you can get different performance characteristics.
Passing fixed compile-time (and thus interned) strings to preg_match to check its performance isn't realistic anyway, microbenchmarks can be deceiving.
Some common use cases have fast paths, so you can always find cases where functions behave differently because of what's commonly found in real-world code.
Closing as not a bug.
@lazerg Thank you for pointing out the underlying mechanisms:
Interned strings do not get a flag IS_STR_VALID_UTF8 after UTF-8 validation - and thereby need constant re-evaluation.
@ndossche About common use cases:
Might the general performance get improved by implementing these two measures:
String concatenation: On concat of two strings that both are already flagged IS_STR_VALID_UTF8, also flag the resulting string without further check.
Edit: already implemented.
Concatenating two valid UTF-8 strings produces a valid UTF-8 string 64127b6
Introduce convenience macros for copying flags that hold when concatenating two strings 99b8614
Fix #97836 and #81705: Segfault / type confusion in concat_function 727e26f
Add op_cache optimization: check interned strings if they are ASCII-only - and then give them a lifetime flag IS_STR_VALID_UTF8.
A general performance improvement idea, wrt the UTF8 flag, would be to find a way to update the flags of zend_strings in shm in a lockless and safe way. This should be doable.
Add op_cache optimization: check interned strings if they are ASCII-only - and then give them a lifetime flag IS_STR_VALID_UTF8.
@iluuu1994 prototyped a compile-time UTF-8 check at one point
Activity
lazerg commentedon Oct 17, 2026
This is expected. With
/u, preg_match() checks that the subject is valid UTF-8, then marks the string so later calls skip the check, but it can't mark interned strings (php_pcre.c). Only D is built at runtime; A and C are compile-time literals, and so is B since 8.4 (#14546).ndossche commentedon Oct 17, 2026
Indeed, depending on how something is compiled or how something is initialized, you can get different performance characteristics.
Passing fixed compile-time (and thus interned) strings to preg_match to check its performance isn't realistic anyway, microbenchmarks can be deceiving.
Some common use cases have fast paths, so you can always find cases where functions behave differently because of what's commonly found in real-world code.
Closing as not a bug.
rr-it commentedon Oct 18, 2026
@lazerg Thank you for pointing out the underlying mechanisms:
Interned strings do not get a flag
IS_STR_VALID_UTF8after UTF-8 validation - and thereby need constant re-evaluation.@ndossche About common use cases:
Might the general performance get improved by implementing these two measures:
String concatenation: On concat of two strings that both are already flagged
IS_STR_VALID_UTF8, also flag the resulting string without further check.Edit: already implemented.
Add op_cache optimization: check interned strings if they are ASCII-only - and then give them a lifetime flag
IS_STR_VALID_UTF8.rr-it commentedon Oct 18, 2026
This might be somehow related to: #20984
ndossche commentedon Oct 19, 2026
A general performance improvement idea, wrt the UTF8 flag, would be to find a way to update the flags of zend_strings in shm in a lockless and safe way. This should be doable.
@iluuu1994 prototyped a compile-time UTF-8 check at one point