Repository navigation
Let another program that loads the phar use PHPStan Turbo - #6720
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Thank you! Sorry for keeping you wait for a week. You can now resume sending improvements to Rector 😊 Because this needs unreleased ^2.3.2, maybe do a single branch with proof of concept of enabling Turbo all the way in Rector and have actual measurements in hand. Of course if there's more to be donr in Rector without this API, could be done as preparation work before without needing ^2.3.2. |
|
Thanks. The proof of concept is on https://github.com/SanderMuller/rector-src/tree/turbo-poc. It requires It has two commits:
On rector-src itself, a cold
These are medians, with the range in brackets. The output is the same in all 10 runs. In a separate run, a probe showed Turbo active, trusted types on and OPcache on in the main process and all 14 workers. Two things are still open. The branch only handles rector-src's own layout: when Rector is installed as a dependency, PHPStan is loaded with the project's autoloader, after |
|
Numbers on a bigger project. I ran the PoC on Shopware v6.7.6.2 with its own
These are medians, with the range in brackets. All 10 runs change the same 14 files with the same diffs. One correction to my rector-src numbers above. The base arm there was two upstream Rector commits older than the PoC, and one of them is the perf change rectorphp/rector-src#8687. Now the PoC is the only difference between the arms. With that base, rector-src goes from 11.9 s to 8.7 s, and from 99.5 s to 61.6 s of CPU. So the earlier result holds. Two notes on the Shopware run. Its |
Rector loads PHPStan's phar from
vendor/phpstan/phpstan, and it gets a lot faster with PHPStan Turbo. On rector-src with its ownrector.php, Rector takes 7.9 s instead of 11.8 s, and 60 s of CPU instead of 98 s. Those are medians of 5 cold runs with 14 workers, on an M4 Pro with PHP 8.5. Rector calls the API below, with a phar built from this branch. The output is the same with and without Turbo.To get there, Rector needs the same three calls as
bin/phpstan. But these calls find the phar throughPhar::running(), which is empty when Rector is the script that runs.This adds an optional
?string $pharPathtoTurboProcessRestarter::restartIfSuitable(),TurboExtensionEnabler::trustOwnTypesIfSuitable()andTurboExtensionEnabler::activateIfCompatible(), and toTurboExtensionSelector::findExtension()andfindExtensionForWorkers(), which they call. Without the argument, nothing changes. The three methods that another program calls are now@api. A path that is passed in goes throughrealpath(). Code compiled from the phar carries the resolved path that Composer'sbootstrap.phpopens it with. Withoutrealpath(), a path likebin/../vendor/...switches trusted types on, but they have no effect.tests/bootstrap.phpcallsactivateIfCompatible(), so itsphpstanApi.methodignore is not needed any more.Rector would call them right after its Composer autoloader:
Its workers start as new processes, so each of them restarts once in the same way. I checked the main process and all 14 workers. In each one the extension is active and OPcache is on. A class-typed parameter check in the phar is dropped, the same as inside PHPStan. With Rector's
--debug, the checks stay, like with PHPStan's.Rector needs two changes of its own. One is merged: rectorphp/rector-src#8564 removes extra arguments to the
TypeTraversercallback, which the native callback rejects. The other is still to do: Rector'spreload.phpmust skipPhpParser\NodeTraverserwhen Turbo has already declared it.make testsandmake phpstanpass, and phpcs reports no errors on the changed files.🤖 Generated with Claude Code