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
Running phpstan with -dopcache.file_cache=/tmp/phpstan/opcache can reduce execution time by 30% #6694
With this I'm getting ~30% reduction in time on a phpstan with phpstan-symfony and phpstan-doctrine, or a more modest 15-20% without any extensions. I attribute this to the fact that phpstan-symfony and phpstan-doctrine are loading a lot of classes outside of phpstan, but I may be wrong.
I believe that when opcache.file_cache is set, every compiled file is cached both in the SHM and the file cache (unless the SHM is full, in which case the file is stored only in cache). The SHM is not persistent in a cli context (everything that's cached is lost when the script finishes), unlike the file cache, which is why the file cache is useful here.
I confirm that it is not possible to ini_set() these settings, unfortunately.
It could be possible to restart the process (like xdebug-handler does to disable xdebug), but the overhead may cancel the effect of opcache.file_cache.
It is also possible to specify these settings in the shebang, but I don't know how much it's portable:
The -S option ensures that php -dopcache.enable_cli=1 -dopcache.file_cache=/tmp/phpstan/opcache -dopcache.file_cache_only=1 is properly handled as multiple arguments.
Because of possible segfaults etc. In old php versions etc, IMO this should be a opt-in (or at least a opt-out should be possible).
What do you think about the idea to start only the worker processes with this opcache-file args and lets see whether this already brings most of the benefits while also gives us the flexibility to decide at php level whether the feature should be enabled or not
This isn't needed - if you don't run with --debug then on dev-master everything runs through a separate process, even analysing a single file, thanks to this commit: phpstan/phpstan-src@2159057
FWIW, PHP subprocesses on Windows reuse the same SHM if they have the same value for opcache.cache_id. On *nix, only forked instances reuse SHM and subprocesses don't. So the behaviour will differ on Windows vs *nix. However file cache should behave the same.
Running this on PM @ pmmp/PocketMine-MP@3e90c30, I don't see any clear performance gain. In fact, local testing indicates that this actually makes performance slightly worse on all counts.
type
with cache (s) first run
with cache (s) second run
without cache (s)
result cache
2.0
1.5
1.27
full analyse
12.03
11.8
11.63
These numbers were obtained using a Dell XPS 17 2021 with an i7-11800H running Windows 11. This machine has a PCIe4 NVMe so the disk speed is not an issue. Tests were ran multiple times to ensure consistency. I saw fluctuations of no more than 0.1s.
Activity
ondrejmirtes commentedon Feb 24, 2022
Do you think there's a way to force this by calling
ini_setetc. before the analysis? :)staabm commentedon Feb 24, 2022
The cache file needs to be defined at the time the php command is invoked. When php is running its already to late to define it.
AFAIK the worker processes are started by the main phpstan process and at that time the argument could be passed
staabm commentedon Feb 24, 2022
Similar topic: maybe it would also be worth it to explore usage of a php preload file
https://www.php.net/manual/de/opcache.configuration.php
ondrejmirtes commentedon Feb 25, 2022
I'm trying this setting but I'm not seeing any improvements.
From the PHP docs:
Maybe my SHM memory isn't full and that's why I'm not seeing this? So the 30 % improvement isn't a universal thing.
staabm commentedon Feb 25, 2022
I also tried it today locally on my windows pc with the following changes in php.ini:
I can see a consistent 16-18% reduction in time.
before 55 secs
after 46 secs
arnaud-lb commentedon Feb 26, 2022
Here is the full command I'm using for testing:
With this I'm getting ~30% reduction in time on a phpstan with phpstan-symfony and phpstan-doctrine, or a more modest 15-20% without any extensions. I attribute this to the fact that phpstan-symfony and phpstan-doctrine are loading a lot of classes outside of phpstan, but I may be wrong.
I believe that when
opcache.file_cacheis set, every compiled file is cached both in the SHM and the file cache (unless the SHM is full, in which case the file is stored only in cache). The SHM is not persistent in a cli context (everything that's cached is lost when the script finishes), unlike the file cache, which is why the file cache is useful here.I confirm that it is not possible to ini_set() these settings, unfortunately.
It could be possible to restart the process (like xdebug-handler does to disable xdebug), but the overhead may cancel the effect of opcache.file_cache.
It is also possible to specify these settings in the shebang, but I don't know how much it's portable:
The
-Soption ensures thatphp -dopcache.enable_cli=1 -dopcache.file_cache=/tmp/phpstan/opcache -dopcache.file_cache_only=1is properly handled as multiple arguments.staabm commentedon Feb 26, 2022
Because of possible segfaults etc. In old php versions etc, IMO this should be a opt-in (or at least a opt-out should be possible).
What do you think about the idea to start only the worker processes with this opcache-file args and lets see whether this already brings most of the benefits while also gives us the flexibility to decide at php level whether the feature should be enabled or not
ondrejmirtes commentedon Feb 26, 2022
This isn't needed - if you don't run with
--debugthen on dev-master everything runs through a separate process, even analysing a single file, thanks to this commit: phpstan/phpstan-src@2159057dktapps commentedon Mar 3, 2022
FWIW, PHP subprocesses on Windows reuse the same SHM if they have the same value for
opcache.cache_id. On *nix, only forked instances reuse SHM and subprocesses don't. So the behaviour will differ on Windows vs *nix. However file cache should behave the same.dktapps commentedon Mar 3, 2022
Running this on PM @ pmmp/PocketMine-MP@3e90c30, I don't see any clear performance gain. In fact, local testing indicates that this actually makes performance slightly worse on all counts.
These numbers were obtained using a Dell XPS 17 2021 with an i7-11800H running Windows 11. This machine has a PCIe4 NVMe so the disk speed is not an issue. Tests were ran multiple times to ensure consistency. I saw fluctuations of no more than 0.1s.
staabm commentedon Mar 3, 2022
@dktapps did you make sure php is actually writing opcache files?
Its pretty easy to miss something in the php.ini and even if you think php would use the file-cache it actually doesn't.
dktapps commentedon Mar 3, 2022
Yes, I did.
ondrejmirtes commentedon Oct 26, 2024
It's too risky to do this - opcache and JIT have bugs so instead of possible performance gain, we might make PHPStan crash on people's computers.
github-actions commentedon Nov 27, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
ondrejmirtes commentedon Sep 1, 2026
Finally making this a reality: phpstan/phpstan-src#6324
Enabling OPCache makes sense when forking workers (not spawning). Keeping JIT off because that one might show problems in forks.
I can measure 10 % improvement in CPU time after this PR.