Share one NamespaceUses between the exported PHPDocs of a file - #6585
Merged
Merged
Conversation
ExportedPhpDocNode held its own copy of the namespace, the uses and the constUses of the file, so the exportedNodes in the result cache grew with the number of imports times the number of documented members. It now refers to the NamespaceUses that NamespaceUsesTracker hands out, which is one instance until the next namespace or use statement, and serialize() writes it once per result cache frame. A parallel worker sends the exported nodes as JSON, which repeats the uses for every PHPDoc. ParallelAnalyser decodes the nodes of each file with an ExportedNodeDecoder, passed through every decode() method, that hands out one NamespaceUses for equal values - so the main process holds the imports of a file once as well, and the result cache stays shared. Full self-analysis (parallel, result cache cleared), identical in two repeats: resultCache.php 54.9 MB -> 51.8 MB, peak RSS of the main process 461 MB -> 453 MB. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0182BrC263VCQTibEPTJX2UY
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.
Follow-up to #6583.
ExportedPhpDocNodeheld its own copy of the file's namespace,usesandconstUses. TheexportedNodesin the result cache therefore grew with the number of imports times the number of documented members. This is the same problem #6583 fixed in the file cache.ExportedPhpDocNodenow refers to theNamespaceUsesthatNamespaceUsesTrackerhands out.serialize()writes it once per result cache frame (one frame per file).ParallelAnalysernow decodes each file's nodes with anExportedNodeDecoder, which returns the sameNamespaceUsesinstance for equal values. The decoder is passed explicitly through everydecode()method, so there is no static state. The main process then holds a file's imports once, and the result cache it writes stays shared.ResultCacheManager::CACHE_VERSIONis bumped because the serialized shape ofExportedPhpDocNodechanged.None of the
ExportedNodeclasses are@api.Numbers
Full self-analysis (parallel, result cache cleared), identical in two repeats:
resultCache.phpThe saving grows with imports × documented members, so the monolith in phpstan/phpstan#15304 should see a much larger difference.
Test
ExportedNodeResolverTest::testUsesAreStoredOncePerFilechecks that the serialized exported nodes of a file contain each import once, both straight from the resolver and after a JSON round trip throughdecode(). The decoded nodes also have to beequals()to the originals. The test fails with 5 copies instead of 1 when either the resolver side or the decoder side stops sharing.🤖 Generated with Claude Code
https://claude.ai/code/session_0182BrC263VCQTibEPTJX2UY