Repository navigation
perf(engine): create the parser and the name resolver on the first parse - #238
Merged
Merged
Conversation
The composer "files" bootstrap of this package calls ReflectionEngine::init() on every request of an application that installs it, and init() built the PHP-Parser parser, lexer and name resolving traverser right away. Most requests never parse anything: in goaop/framework, parsing only happens on a cache miss. init() now only stores the locator and the grammar version, getParser() and parseFile() create the parser and the traverser on first use. The ComposerLocator stays eager on purpose: it must find composer's own class loader before other loaders wrap it. Warm request with opcache (built-in server, median of 200): requiring vendor/autoload.php of goaop/framework takes 87-91 instead of 229-242 µs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019bYFRwMWKndKaj6SemwDn2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Part of goaop/framework#730.
src/bootstrap.phpis a composerfilesautoload entry, so it runsReflectionEngine::init(new ComposerLocator())on every request of every application that has this package installed.init()built the PHP-Parser parser, the emulative lexer and the name-resolving traverser right away. Most requests never parse anything; in goaop/framework, for example, parsing only happens when the transformed-code cache misses.Change
init()only stores the locator and the optional grammar version. It also resets any previously created parser and traverser, so a re-init()with anotherPhpVersionstill takes effect.getParser()creates the parser on first use. A new privategetTraverser()does the same for the traverser.parseFile()uses both.ComposerLocatorstays eager on purpose. It looks up composer's ownClassLoaderinspl_autoload_functions(), and goaop/framework later wraps that loader, after which a lazy lookup would find noClassLoader.$parserand$traverserbecome nullable (?Parser = null,?NodeTraverser = null) so thatinit()can reset them.Measured. goaop/framework app, PHP 8.5, opcache with
validate_timestamps=0, JIT off, built-in server, median of 200 warm requests.require vendor/autoload.phptakes 229–242 µs → 87–91 µs, about 145 µs saved per request.Backport. The 4.x branch, which serves PHP 8.4 installs, has the same eager
init(). A cherry-pick of this commit applies to it.Tests
tests/ReflectionEngineTest.php:init()creates no parser and no traverser;PhpVersiongiven toinit()is honoured: an 8.4 grammar rejects the pipe operator;parseFile()creates both and resolves names.vendor/bin/phpstan analyse src: no errors.🤖 Generated with Claude Code
https://claude.ai/code/session_019bYFRwMWKndKaj6SemwDn2
Generated by Claude Code