Skip to content

Instantly share code, notes, and snippets.

@ruudk
Created December 8, 2022 15:35
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruudk/41897eb59ff497b271fc9fa3c7d5fb27 to your computer and use it in GitHub Desktop.
Save ruudk/41897eb59ff497b271fc9fa3c7d5fb27 to your computer and use it in GitHub Desktop.
How to find the files that are the slowest to analyze with PHPStan?

How to find the files that are the slowest to analyze with PHPStan?

For us, PHPStan became a bit slower with every release. We have a very large codebase with 10.000+ classes. There seem to be a few known issues related to big arrays.

See: phpstan/phpstan#8353 phpstan/phpstan#8146

To understand which files are problematic we run the following command:

vendor/bin/phpstan analyze --memory-limit=-1 --debug -vvv | tee phpstan.log

Then we run:

php parse.php
<?php
declare(strict_types=1);
$log = new SplFileObject("phpstan.log");
$logs = [];
$file = null;
while (! $log->eof()) {
$line = trim($log->fgets());
if ($line === '') {
continue;
}
if ($file === null) {
$file = $line;
continue;
}
preg_match('/took (?<seconds>[\d.]+) s/', $line, $matches);
$logs[] = [(float) $matches['seconds'], $file];
$file = null;
}
usort($logs, fn(array $left, array $right) => $right[0] <=> $left[0]);
$logs = array_slice($logs, 0, 100);
echo "Slowest files" . PHP_EOL;
foreach ($logs as $log) {
echo sprintf("%.2f seconds: %s", $log[0], $log[1]) . PHP_EOL;
}
@szepeviktor
Copy link

szepeviktor commented Dec 21, 2022

For those who could use a shell one-liner:

vendor/bin/phpstan analyze --memory-limit=-1 --debug -vvv | sed -e 'N; s#\n# #; s#^\(\S\+\) .* \(\S\+\) s$#\2 \1#; /^ /d' | sort -n

@senki
Copy link

senki commented Jan 2, 2023

I made a rust version as part of a learning exercise.

(I hope this self-plug is OK)

@gnutix
Copy link

gnutix commented Jun 23, 2023

I got an undefined array key 'seconds' error, fixed by adding this piece of code after the preg_match call :

    if (!array_key_exists('seconds', $matches)) {
        continue;
    }

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