Skip to content

Running phpstan with -dopcache.file_cache=/tmp/phpstan/opcache can reduce execution time by 30% #6694

Closed

Description

@arnaud-lb

Feature request

Running phpstan with -dopcache.file_cache=/tmp/phpstan/opcache can reduce execution time by 30% when analyzing a single file.

This enhances the experience of the phpstan integration in phpstorm or vim, for example.

Activity

  1. ondrejmirtes commented on Feb 24, 2022

    @ondrejmirtes
    Member

    Do you think there's a way to force this by calling ini_set etc. before the analysis? :)

  2. staabm commented on Feb 24, 2022

    @staabm
    Contributor

    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

  3. staabm commented on Feb 24, 2022

    @staabm
    Contributor

    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

  4. ondrejmirtes commented on Feb 25, 2022

    @ondrejmirtes
    Member

    I'm trying this setting but I'm not seeing any improvements.

    From the PHP docs:

    It should improve performance when SHM memory is full, at server restart or SHM reset.

    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.

  5. staabm commented on Feb 25, 2022

    @staabm
    Contributor

    I also tried it today locally on my windows pc with the following changes in php.ini:

    zend_extension=opcache
    opcache.enable_cli=1
    opcache.file_cache=c:/temp/php-opcache
    opcache.jit=disabled
    

    I can see a consistent 16-18% reduction in time.

    before 55 secs
    after 46 secs

  6. arnaud-lb commented on Feb 26, 2022

    @arnaud-lb
    ContributorAuthor

    Here is the full command I'm using for testing:

    php -n -dzend_extension=opcache.so -dopcache.enable_cli=1 -dopcache.file_cache=/tmp/phpstan/opcache -dopcache.file_cache_only=1  vendor/bin/phpstan analyze -l 9 src/Doctrine/Mapping/MappingDriverChain.php
    

    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:

    #!/usr/bin/env -S php -dopcache.enable_cli=1 -dopcache.file_cache=/tmp/phpstan/opcache -dopcache.file_cache_only=1
    <?php
    

    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.

  7. staabm commented on Feb 26, 2022

    @staabm
    Contributor

    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

  8. ondrejmirtes commented on Feb 26, 2022

    @ondrejmirtes
    Member

    It could be possible to restart the process

    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

  9. dktapps commented on Mar 3, 2022

    @dktapps
    Contributor

    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.

  10. dktapps commented on Mar 3, 2022

    @dktapps
    Contributor

    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.

  11. staabm commented on Mar 3, 2022

    @staabm
    Contributor

    @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.

  12. dktapps commented on Mar 3, 2022

    @dktapps
    Contributor

    @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.

    Yes, I did.

  13. ondrejmirtes commented on Oct 26, 2024

    @ondrejmirtes
    Member

    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.

  14. github-actions commented on Nov 27, 2024

    @github-actions

    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.

  15. locked as resolved and limited conversation to collaborators on Nov 27, 2024
  16. ondrejmirtes commented on Sep 1, 2026

    @ondrejmirtes
    Member

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions