|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74250 OPcache compilation performance regression in PHP 5.6/7 with huge classes
Submitted: 2017-03-15 09:36 UTC Modified: 2017-03-17 12:12 UTC
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: dzuelke at gmail dot com Assigned: nikic (profile)
Status: Closed Package: opcache
PHP Version: 7.0.16 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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: dzuelke at gmail dot com
New email:
PHP Version: OS:


 [2017-03-15 09:36 UTC] dzuelke at gmail dot com
There appears to be a performance regression in the CFG and DFA based optimization passes of OPcache in PHP 5.6+ when loading huge classes (such as those generated by Symfony's routing component) for the first time.

The issue does not occur on PHP 5.5. Tests below are with 5.6.30, 7.0.16 and 7.1.2 and default INI settings; I replicated the issue on both macOS and Linux.

Test file here (it's from an actual application, slightly anonymized, not a synthetic example):

Without OPcache, everything is fine in all versions:

$ time -p php -dopcache.enable_cli=0 hugeclass.php 
real 0.10
user 0.09
sys 0.00

With OPcache on, things are suddenly much, much slower:


$ time -p php -dopcache.enable_cli=1 hugeclass.php
real 3.23
user 3.21
sys 0.02


$ time -p php -dopcache.enable_cli=1 hugeclass.php
real 1.76
user 1.73
sys 0.02


$ time -p php -dopcache.enable_cli=1 hugeclass.php
real 4.01
user 3.98
sys 0.02

For comparison, 5.5 is as speedy as you'd expect it to be:

$ time -p php -dopcache.enable_cli=1 hugeclass.php 
real 0.14
user 0.11
sys 0.02

If we switch off optimization passes 5 (CFG based) and 6 (DFA based, only in 7.1), everything is great again in all versions:

$ time -p php -dopcache.enable_cli=1 -dopcache.optimization_level=0x7FFFFFCF hugeclass.php
real 0.13
user 0.10
sys 0.02

For 5.6 and 7.0, pass 6 is not a thing, but in 7.1, we can inspect passes 5 and 6 separately.

Pass 5 (CFG based) already makes for a drastic performance hit in 7.1:

$ time -p php -dopcache.enable_cli=1 -dopcache.optimization_level=0x7FFFFFDF hugeclass.php
real 0.88
user 0.86
sys 0.01

But pass 6 (DFA based) is the one that causes the biggest slowdown in 7.1:

$ time -p php -dopcache.enable_cli=1 -dopcache.optimization_level=0x7FFFFFEF hugeclass.php
real 3.29
user 3.24
sys 0.04

In all versions, subsequent loads from the cache (such as when running FPM or the built-in web server) are fast.

Confirmed as bug in both CFG and DFA passes by Nikita:

Test script:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-16 00:33 UTC]
-Assigned To: +Assigned To: nikic
 [2017-03-17 12:12 UTC]
-Status: Assigned +Status: Closed
 [2017-03-17 12:12 UTC]
Relevant commits for the DFA pass:

Call lookup:
Loop identification / DJ spanning tree:
Worklist management:

Resolving the performance problems in the block pass would require some larger changes. Instead I disabled it entirely for large functions (the sample file is 20x over the threshold):
 [2017-03-17 17:20 UTC] dzuelke at gmail dot com
Fantastic, thank you so much Nikita! I assume this will this be backported to the 7.0 branch as well?
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sun Dec 03 04:01:27 2023 UTC