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

SlevomatCodingStandard\Helpers\TokenHelper#findPrevious() is very expensive, and chokes on files with many use statements #1657

Open
Ocramius opened this issue Jan 25, 2024 · 4 comments

Comments

@Ocramius
Copy link

I just analyzed a project where a file with tons of use statements easily slows down PHPCS in a quadratic way.

Specifically, the SlevomatCodingStandard\Helpers\TokenHelper#findPrevious() (relatively lightweight) is used in:

  • UseFromSameNamespaceSniff
  • MultipleUsesPerLineSniff
  • UseDoesNotStartWithBackspaceSniff

Along other code locations, like the SniffLocalCache and UseStatementHelper.

IT seems like PHP_CodeSniffer\Files\File#findPrevious() is extremely slow and complex, and iterates over the entire tokens of a file starting from the end: this obviously is problematic when the source code increases in size, and we're analyzing use statements.

I'm wondering whether we should try and optimize the TokenHelper in this project, by minimuizing #findPrevious() calls, or in PHP_CodeSniffer itself, by optimizing the main loop there 🤔

/cc @MatteoBiagini

Here's a rough profile screenshot, to make this a bit more visible:

phpcs-xdebug-profile-sorted-by-self-execution-time

@kukulich
Copy link
Contributor

It's probably possible to find some optimization here for isTraitUse(). However I think the best solution would be to split T_USE token to three tokens in PHPCS...

@Ocramius
Copy link
Author

That would be a major-major BC break, no? :D

@kukulich
Copy link
Contributor

kukulich commented Mar 9, 2024

I've just tried to optimize it in 5cac991

@Ocramius
Copy link
Author

Awesome! Happy to report once I get a renovate downstream update 💪

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

No branches or pull requests

2 participants