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

Reduce memory consumption of TypeInferenceTestCase #2644

Closed
wants to merge 1 commit into from

Conversation

staabm
Copy link
Contributor

@staabm staabm commented Sep 24, 2023

reduce the data beeing transfered between dataProvider and tests, by using just scalar values instead of objects with complex graphs which needs a lot of memory/time to serialize.


refs phpstan/phpstan#9914

repro https://github.com/gnutix/phpstan-typeinferencetest-memory-exhausted

before this PR

➜  memopt git:(main) ✗ vendor/bin/phpunit --no-results

PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.10
Configuration: /Users/staabm/workspace/memopt/phpunit.xml.dist

FFF....FF....FFFFFFFFFFFFFFFFFFFFF........FFF....F.F.....FFFFFF  63 / 168 ( 37%)
F......FFFFF.FFF................FFFFF.....F.....FFFFFFFFF...... 126 / 168 ( 75%)
FFFFFFFFF.......F.....FFFF............FF..                      168 / 168 (100%)

Time: 00:27.074, Memory: 5.38 GB

after this PR

 memopt git:(main) ✗ vendor/bin/phpunit --no-results

PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.10
Configuration: /Users/staabm/workspace/memopt/phpunit.xml.dist

FFF....FF....FFFFFFFFFFFFFFFFFFFFF........FFF....F.F.....FFFFFF  63 / 168 ( 37%)
F......FFFFF.FFF................FFFFF.....F.....FFFFFFFFF...... 126 / 168 ( 75%)
FFFFFFFFF.......F.....FFFF............FF..                      168 / 168 (100%)

Time: 00:00.042, Memory: 82.00 MB

=> ~98% memory improvement

@ondrejmirtes
Copy link
Member

The time makes me suspicious about this change and the benchmark.

@staabm
Copy link
Contributor Author

staabm commented Sep 24, 2023

The results are similar to the ones sugggested in the initial report of phpstan/phpstan#9914

The blackfire profiles of the report also show a 99% cost of data serialization

@staabm
Copy link
Contributor Author

staabm commented Sep 24, 2023

The time makes me suspicious about this change and the benchmark.

I did more in detail work and found the reason/circumstances when this patch shines:

phpstan/phpstan#9914 (reply in thread)

only when tests are written with global code which gets executed this improvement is necessary.
people should not write tests like this, but I think having this small patch merged to reduce the overhead for this case - because not everyone knows how the best practice looks like - would be a good thing

@ondrejmirtes
Copy link
Member

Please push your branch with the modified test code (move asserts into closures) so that I can see for myself.

@staabm
Copy link
Contributor Author

staabm commented Sep 24, 2023

see https://github.com/staabm/phpstan-typeinferencetest-memory-exhausted/tree/closures

via enabling this line, you can "enable" the change of this PR

I removed a few test files of the origin repro because it was too massive slow to work with

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

reproducer of the initial reported problem within the PHPStan codebase itself: #2647

in the repro we can also see that the fix of this PR here fixes the problem in phpunit10

@ondrejmirtes
Copy link
Member

I think we can close this, the root issue was addressed in PHPUnit.

@staabm staabm closed this Sep 25, 2023
@staabm staabm deleted the memopt branch September 25, 2023 07:39
@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

agree. upstream fix was in sebastianbergmann/phpunit#5524

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

@gnutix on my laptop I can reproduce that https://github.com/staabm/phpstan-typeinferencetest-memory-exhausted/tree/main makes phpunit slow and hang, while https://github.com/staabm/phpstan-typeinferencetest-memory-exhausted/tree/closures - where I have wrapped the tests in closures - finishes nearly instant using time vendor/bin/phpunit --no-results


mstaab@NB-COMPLEX-61 MINGW64 /c/dvl/Workspace/phpstan-typeinferencetest-memory-exhausted (closures)
$ time vendor/bin/phpunit --no-results
PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.7
Configuration: C:\dvl\Workspace\phpstan-typeinferencetest-memory-exhausted\phpunit.xml.dist

.FFFFFF..F.F....F.FFFFFFFFFFFF                                    30 / 30 (100%)

Time: 00:00.030, Memory: 64.00 MB


real    0m1.236s
user    0m0.000s
sys     0m0.000s

mstaab@NB-COMPLEX-61 MINGW64 /c/dvl/Workspace/phpstan-typeinferencetest-memory-exhausted (main)
$ time vendor/bin/phpunit --no-results
PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.7
Configuration: C:\dvl\Workspace\phpstan-typeinferencetest-memory-exhausted\phpunit.xml.dist

...........F......FFFFFFFFFFFFFFFFF.....F.FFFFF.....FF.........  63 / 168 ( 37%)
...FF.FFFFFFFF.....FFF.FFF..FFF.FFFF.....FF....F.FFFFFFFFFF.... 126 / 168 ( 75%)
.........FFF....FF.FFF........FFFF.....FFF                      168 / 168 (100%)

Time: 00:48.006, Memory: 5.47 GB


real    1m34.071s
user    0m0.000s
sys     0m0.000s

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

ohh hold on a second. I just realized my closure branch also cotained a change which updated phpunit. that might be a red hering.

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

I just force-pushed a new revision into the closure branch and got a different result:

main branch

mstaab@NB-COMPLEX-61 MINGW64 /c/dvl/Workspace/phpstan-typeinferencetest-memory-exhausted (main)

$ time vendor/bin/phpunit --no-results
PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.7
Configuration: C:\dvl\Workspace\phpstan-typeinferencetest-memory-exhausted\phpunit.xml.dist

...........F......FFFFFFFFFFFFFFFFF.....F.FFFFF.....FF.........  63 / 168 ( 37%)
...FF.FFFFFFFF.....FFF.FFF..FFF.FFFF.....FF....F.FFFFFFFFFF.... 126 / 168 ( 75%)
.........FFF....FF.FFF........FFFF.....FFF                      168 / 168 (100%)

Time: 00:43.266, Memory: 5.47 GB


real    1m27.093s
user    0m0.000s
sys     0m0.000s

closure branch: (only 7 of the 31 tests have been wrapped)

$ time vendor/bin/phpunit --no-results
PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.7
Configuration: C:\dvl\Workspace\phpstan-typeinferencetest-memory-exhausted\phpunit.xml.dist

.FFFFFF..F.F....F.FFFFFFFFFFFFFFFFF.....F.FFFFF.....FF.........  63 / 168 ( 37%)
...FF.FFFFFFFF.....FFF.FFF..FFF.FFFF.....FF....F.FFFFFFFFFF.... 126 / 168 ( 75%)
.........FFF....FF.FFF........FFFF.....FFF                      168 / 168 (100%)

Time: 00:34.683, Memory: 4.52 GB


real    1m10.589s
user    0m0.000s
sys     0m0.000s

there still is a big difference, but not as big as I initially reported

@gnutix
Copy link
Contributor

gnutix commented Sep 25, 2023

OK, that's aligned with what I get locally. For now, I can't use the data providers in my TypeInferenceTest, as I can't yet upgrade to PHPUnit 10.4.x yet (it's still a dev branch, and some dependencies are not yet compatible with it). Even with sebastian/exporter 5.1.1 (sprintf fix), using glob() instead of Symfony's Finder and wrapping all test files in closures, running the full Functional's TypeInferenceTest still results in :

$ php vendor/bin/phpunit -d memory_limit=8G vendor-unmanaged/gammadia/collections/phpstan/tests/Functional/Extensions/TypeInferenceTest.php
PHPUnit 10.3.5 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.7
Configuration: /app/phpunit.xml.dist

...............................................................  63 / 168 ( 37%)
............................................................... 126 / 168 ( 75%)
..........................................                      168 / 168 (100%)

Time: 01:26.282, Memory: 4.06 GB

OK (168 tests, 336 assertions)

So I guess I need to wait for PHPUnit 10.4 to be released and its dependencies to be ready, and then I'll be able to add the data providers again.

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

if not too much work, you might be happy with phpunit9 until then

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

or alternativly you use #2644 in the meantime

@gnutix
Copy link
Contributor

gnutix commented Sep 25, 2023

if not too much work, you might be happy with phpunit9 until then

I just upgraded everything to PHPUnit 10, so thanks but no thanks! 😆

or alternativly you use #2644 in the meantime

Not sure how I can do that, as PHPStan comes as a PHAR and all. 🤷‍♂️

No biggie, I don't really mind not having the data provider for a few weeks/months.

@staabm
Copy link
Contributor Author

staabm commented Sep 25, 2023

Not sure how I can do that, as PHPStan comes as a PHAR and all. 🤷‍♂️

in my tests I just put the TypeInferenceTestCase.php into a file of the repo and direcly required it from the phpunit autoload file.
that way it will be used and not autoloaded from within the phpstan.phar

but if you can live without it - thats the easiest thing to stay

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

Successfully merging this pull request may close these issues.

3 participants