[php-src] PR #25243: Fix GH-9993: Bad performance with hard-coded GC_THRESHOLD_* values
| From: | kamil-tekiela | Date: | Fri, 06 Nov 2026 16:30:34 +0000 |
| Subject: | [php-src] PR #25243: Fix GH-9993: Bad performance with hard-coded GC_THRESHOLD_* values | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-40357@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/25243
Author: kamil-tekiela
The GC raised its threshold only when a run collected fewer than 100
nodes. A run that traverses a large live graph but also frees some
garbage kept the threshold at 10001, so the GC traversed the whole live
graph again after every 10000 new roots. Test suites that keep large
object graphs alive spent most of their time in the GC after
GH-9266 fixed the count that the threshold rule uses.
Count the nodes that a run traverses. After the run, set the threshold
to at least (traversed - collected) / 8, so that the cost of a run is
paid for by the roots added before the next run. The old step rule
still sets the base threshold:
* The threshold falls back to the base threshold as soon as a run
stops traversing the live graph.
* The threshold resets to the base threshold at request startup, as
the live graph belongs to the request.
* The root buffer grows to the new threshold with one reallocation.
A higher threshold makes each run free a larger batch of garbage, which
fits less well in the CPU cache and keeps garbage alive for longer. A
ratio of 4 was faster for large live graphs, but raised peak memory by
up to 43% and slowed down a 100k node live graph with large garbage
cycles by 40%. With a ratio of 8 that case is 5-13% slower, and peak
memory did not change in any measured case.
Scripts with small live graphs keep the old threshold. With a live
graph of 1M nodes that the script touches while it creates garbage
cycles, the run time drops from 24.2s to 3.3s.
Fixes GH-9993.