staabm / phpstan-dba

PHPStan based SQL static analysis and type inference for the database access layer
https://staabm.github.io/archive.html#phpstan-dba
MIT License
250 stars 17 forks source link

Enabling `staabm/phpstan-dba` significantly increases garbage collection activity #667

Open glaubinix opened 1 month ago

glaubinix commented 1 month ago

We noticed that since we enabled staabm/phpstan-dba in our project, a full PHPStan run without cache takes significantly longer than without it.

Running it with the extension

php ./vendor/bin/phpstan --debug  537.54s user 3.92s system 97% cpu 9:13.27 total

Running it without the extension

php ./bin/phpstan --debug  230.65s user 3.89s system 97% cpu 3:59.47 total

I triggered a trace with Tideways to see why this suddenly takes so much longer and it turns out that about 6min of the run is spent on garbage collection. Turning garbage collection off results in a significant performance boost.

Running it with the extension

php -d zend.enable_gc=0 ./vendor/bin/phpstan --debug  176.72s user 4.04s system 96% cpu 3:06.44 total

Running it without the extension

php -d zend.enable_gc=0 ./vendor/bin/phpstan --debug  153.03s user 3.25s system 98% cpu 2:39.39 total

Is there any chance you encountered similar effects and already have an idea what could cause this? Otherwise, I'll look into some memory profiling in the next days to see if I can find a cause for this. Happy to share additional info but not really sure what might actually be helpful here.

staabm commented 1 month ago

Thanks for the report.

Is the problem reproducible in a minimal repo or similat?

glaubinix commented 1 month ago

As of right now, I haven't been able to reproduce this on smaller repositories. For instance, running PHPStan just on certain subfolders where we have our SQL queries, runs through in a few seconds and garbage collection activity is similar with and without the extension enabled.

staabm commented 1 month ago

which phpstan-dba config options do you use?

maybe you can use tideways to look into where most memory consumption happens, so we can get an idea where all the memory trash is generated.

it might also make sense to disable rules and extensions to narrow it down further

glaubinix commented 1 month ago

The config is more or less the default. Setting debug false/true doesn't make a difference

<?php declare(strict_types=1);

use staabm\PHPStanDba\QueryReflection\PdoPgSqlQueryReflector;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\QueryReflection\RecordingQueryReflector;
use staabm\PHPStanDba\QueryReflection\ReflectionCache;
use staabm\PHPStanDba\QueryReflection\RuntimeConfiguration;

QueryReflection::setupReflector(
    new RecordingQueryReflector(
        ReflectionCache::create(
            __DIR__ . '/../.phpstan-dba.cache',
        ),
        new PdoPgSqlQueryReflector(
            new \PDO('pgsql:host=localhost;port=5432;dbname=database'),
        ),
    ),
    (new RuntimeConfiguration())->debugMode(true),
);

I try to pinpoint this to specific rules/extensions but this might take a while as every run takes a few minutes. Will report back once I have more info.

glaubinix commented 1 month ago

Alright, I figured out what is causing this. If I fully remove

includes:
    - vendor/staabm/phpstan-dba/config/dba.neon

and only configure this one service

services:
    -
        class: staabm\PHPStanDba\Ast\PreviousConnectingVisitor
        tags:
            - phpstan.parser.richParserNodeVisitor

then the run is suddenly 6min longer. The bigger the repository to analyze the bigger the impact.

staabm commented 1 month ago

Thanks for looking into it. I guess its the same problem as https://phpstan.org/blog/preprocessing-ast-for-custom-rules

staabm commented 1 month ago

could you please try whether https://github.com/staabm/phpstan-dba/pull/670 at least helps a bit to reduce your pain?

staabm commented 1 month ago

and please also try https://github.com/staabm/phpstan-dba/pull/671

at best also give your project a try with both PRs applied at the same time, so we know about the impact of each in isolation and also the combination

glaubinix commented 1 month ago

Apologies, somehow I missed the second PR this morning. Unfortunately, no improvements.

php ./bin/phpstan php -d zend.enable_gc=0 ./bin/phpstan
0.2.8.1 9:04.60 3:01.07
less-parents 13:31.71 2:57.27
less-previous 9:20.37 3:00.74
less-both 14:04.19 2:56.77