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

FileExcluder: Improve performance of isExcludedFromAnalysing #728

Merged
merged 2 commits into from Oct 24, 2021
Merged

FileExcluder: Improve performance of isExcludedFromAnalysing #728

merged 2 commits into from Oct 24, 2021

Conversation

dktapps
Copy link
Contributor

@dktapps dktapps commented Oct 23, 2021

I discovered this while debugging phpstan/phpstan#5825.

When analysing pmmp/PocketMine-MP@701a71a with a result cache + no unchanged files, I noticed that isExcludedFromAnalysing() took over 9% of the total time spent. I'm not sure why this is needed when result cache is used, but it became immediately obvious to me that there were performance gains to be had here.

Before analysis, an xdebug profiler snapshot showed that this method took 9% of the total CPU time and called isFnmatchPattern() over 124,000 times. This is pretty bad considering that PM doesn't use fnmatch patterns at all.
isFnmatchPattern() took about 2.7% time.

After the patch, this drops to about 1.9% for isExcludedFromAnalysis() and 0.1% for isFnmatchPattern(), with isFnmatchPattern() now being called only ~2,200 times.

In real numbers, this shaves off a fraction of a second of pre-analysis time when a result cache is used (at least on Windows).

I discovered this while debugging #5825.

When analysing pmmp/PocketMine-MP@701a71a with a result cache + no unchanged files, I noticed that isExcludedFromAnalysing() took over 9% of the total time spent. I'm not sure why this is needed when result cache is used, but it became immediately obvious to me that there were performance gains to be had here.

Before analysis, an xdebug profiler snapshot showed that this method took 9% of the total CPU time and called isFnmatchPattern() over 124,000 times. This is pretty bad considering that PM doesn't use fnmatch patterns at all.
isFnmatchPattern() took about 2.7% time.

After the patch, this drops to about 1.9% for isExcludedFromAnalysis() and 0.1% for isFnmatchPattern(), with isFnmatchPattern() now being called only ~2,200 times.

In real numbers, this shaves off about half a second of pre-analysis time when a result cache is used (at least on Windows).
@ondrejmirtes ondrejmirtes merged commit 669b6cd into phpstan:master Oct 24, 2021
@ondrejmirtes
Copy link
Member

Thank you!

@dktapps
Copy link
Contributor Author

dktapps commented Oct 24, 2021

I do have another suggestion that cuts it by another 10% or so (in my case), which is to use the literal paths for both keys and values in literalAnalyseExcludes. Then in some cases paths can be checked by just doing isset(literalAnalyseExcludes[path]) instead of looping over the whole thing and comparing one by one. But it's really diminishing returns (10% of 2% is 0.2%, so not really any observable difference), so I didn't bother to put it in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants