Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StubValidator::validate() accounts for ~30% of phpstan execution time for a single file #6693

Closed
arnaud-lb opened this issue Feb 24, 2022 · 11 comments

Comments

@arnaud-lb
Copy link
Contributor

Feature request

StubValidator::validate() accounts for ~30% of the execution time for a command like phpstan analyze -l 9 file.php.

(I'm using phpstan-symfony and phpstan-doctrine, which have some number of stubs.)

Reducing these 30% would enhance the experience of the phpstan integration in phpstorm or vim, for example.

@ondrejmirtes
Copy link
Member

There are some things that make it faster:

  1. PHPStan only analyses stubs that are directly mentioned in your phpstan.neon. Switching to phpstan/extension-installer and removing those includes from vendor might help speed it up.
  2. Recently the stub validator results have been put into the result cache, but the result cache is not used when analysing a single file. Honoring advice from this article (https://phpstan.org/blog/why-you-should-always-analyse-whole-project) might also help you. I realize you're talking about IDE integration here, but I believe these should honor this article as well... Time to open some bug reports I guess :)

@arnaud-lb
Copy link
Contributor Author

PHPStan only analyses stubs that are directly mentioned in your phpstan.neon. Switching to phpstan/extension-installer and removing those includes from vendor might help speed it up.

Awesome! I confirm that this speeds things up :)

Recently the stub validator results have been put into the result cache, but the result cache is not used when analysing a single file. Honoring advice from this article (https://phpstan.org/blog/why-you-should-always-analyse-whole-project) might also help you. I realize you're talking about IDE integration here, but I believe these should honor this article as well... Time to open some bug reports I guess :)

I'm using this in CI, but I've found that it's not suitable for commit hooks and IDEs because it can take too long: a few minutes when the cache is invalidated or at least 7-8s on some project when cached.

So I was searching for a way to execute phpstan quickly when I save a file in my editor.

To give you an idea, analyzing the whole project when fully cached takes 7-8s, from which:

  • 6.33% in BetterReflectionSourceLocatorFactory::create() and callees
  • 7.42% in InceptionResult::getFiles() and callees
  • 21% in MemoizingSourceLocator::locateIdentifier() and callees
  • 35% in IgnoredErrorHelper::initialize() and callees (the project has a baseline.neon with 900 items)
  • 20% in ResultCacheManager::process() and callees

@staabm
Copy link
Contributor

staabm commented Feb 28, 2022

@arnaud-lb

35% in IgnoredErrorHelper::initialize() and callees (the project has a baseline.neon with 900 items)

Would phpstan/phpstan-src#744 help you regarding these 35% ?

@arnaud-lb
Copy link
Contributor Author

I think that it would :) IgnoredErrorHelper::initialize() spends most of its time in IngoredRegexValidator::validate(), so definitely yes!

image

@ondrejmirtes
Copy link
Member

Oh, I just got an idea - ignored errors regexes could be validated as part of a DIC compiler extension and thus only once when they are changed, not each time when PHPStan is executed :)

@ondrejmirtes
Copy link
Member

I've almost got it :) But I noticed that the errors from the baseline are not current validated thanks to this line: https://github.com/phpstan/phpstan-src/blob/2d52a5b077b504898fbc78874476b22d18d605d8/src/Analyser/IgnoredErrorHelper.php#L79-L81

So a big baseline doesn't matter here.

@ondrejmirtes
Copy link
Member

Here it is: phpstan/phpstan-src@692158c

Please wait a bit so that it builds and then test phpstan/phpstan:dev-master :) Thanks.

@arnaud-lb
Copy link
Contributor Author

But I noticed that the errors from the baseline are not current validated thanks to this line: https://github.com/phpstan/phpstan-src/blob/2d52a5b077b504898fbc78874476b22d18d605d8/src/Analyser/IgnoredErrorHelper.php#L79-L81
So a big baseline doesn't matter here.

I didn't expect that. It's weird that it was taking so much time then. Hao\Compiler\Llk\Parser::parse() appear to take the most time of IgnoredErrorHelper::initialize() / IgnoredRegexValidator::validate().

Here it is: phpstan/phpstan-src@692158c

Awesome! I confirm that this completely eliminates the IgnoredErrorHelper::initialize() time :) I've also tried removing the count: lines from the baseline (for testing) : Before 692158c194eff722167f5316d31369a188a88a72 this makes phpstan multiple times slower (as expected) and after 692158c194eff722167f5316d31369a188a88a72 this makes no different (proving the cache works).

@ondrejmirtes
Copy link
Member

Alright, can I close this or do you see any other bottleneck that can be solved? 😊

@arnaud-lb
Copy link
Contributor Author

Yes, I'm closing the issue now. Thank you :)

@github-actions
Copy link

github-actions bot commented Apr 6, 2022

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants