php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81243 Too much memory is allocated for the return value of preg_replace
Submitted: 2021-07-11 08:14 UTC Modified: 2021-09-06 17:45 UTC
From: abecker at mailbox dot org Assigned: cmb (profile)
Status: Closed Package: PCRE related
PHP Version: 8.0.8 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: abecker at mailbox dot org
New email:
PHP Version: OS:

 

 [2021-07-11 08:14 UTC] abecker at mailbox dot org
Description:
------------
The string returned by preg_replace uses too much memory - multiples of the actual string size in bytes. For big strings, this can be a significant performance issue.

mb_ereg_replace does not have this problem.

When I copy the returned string using some of the PHP string functions, the storage size is reduced in case the memory for the string is reallocated.

Test script:
---------------
$base_memory = memory_get_usage();
$test_string = str_repeat('Eins zwei drei', 2000);
var_dump(memory_get_usage() - $base_memory);
$replaced = preg_replace('/\s/', '-', $test_string);
var_dump(memory_get_usage() - $base_memory);
$replaced = str_repeat($replaced, 1);
#$replaced = str_replace('e', 'e', $replaced);
#$replaced = $replaced[0] . substr($replaced, 1);
var_dump(memory_get_usage() - $base_memory);


Expected result:
----------------
int(28672)
int(57728)
int(57728)

Actual result:
--------------
int(28672)
int(106880)
int(57728)


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-12 11:25 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2021-07-12 11:25 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #81243: Too much memory is allocated for preg_replace()
On GitHub:  https://github.com/php/php-src/pull/7231
Patch:      https://github.com/php/php-src/pull/7231.patch
 [2021-07-12 16:39 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/php-src/commit/a6b43086e6799eedf02d36ccea103e2b10c1005a
Log: Fix #81243: Too much memory is allocated for preg_replace()
 [2021-07-12 16:39 UTC] git@php.net
-Status: Assigned +Status: Closed
 [2021-09-06 17:02 UTC] nospam at briat dot org
Since this fix preg_replace seems much slower (up to 100 times).

I notice by debuging the https://www.drupal.org/project/advagg module for Drupal 7 which use this cssmin.php v2.4.8-4. By using xdebug profiler I discover that  this lib uses intensively preg_replace which use 99% of the total time.

I made small script that call the lib and compress a css file, here's the total time in seconds with the two version of PHP.

docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:7.4.11-cli-alpine  php test.php
0.19343304634094s

docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:7.4.12-cli-alpine  php test.php
11.722915887833s
 [2021-09-06 17:13 UTC] cmb@php.net
Thanks for reporting!  Since the commit has already shipped (PHP
7.4.22 and 8.0.9), please open a new bug ticket, so we can
properly track the regression.
 [2021-09-06 17:45 UTC] nikic@php.net
It would be great if you could also share the script you're benchmarking (or some reduced version).
 [2021-09-07 17:12 UTC] nospam at briat dot org
I open the issue #81424. It could also be relarted to the PCRE version.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jan 02 12:01:29 2025 UTC