Skip to content

[perf] Skip phpdoc path in RenameClassRector for nodes without a docblock - #8623

Merged
TomasVotruba merged 2 commits into
mainfrom
perf-rename-class-skip-nondoc-nodes
Oct 11, 2026
Merged

TomasVotruba merged 2 commits into
mainfrom
perf-rename-class-skip-nondoc-nodes

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Why

RenameClassRector is one of the heaviest rules. It subscribes to FullyQualified, Name, Property, FunctionLike, Expression, ClassLike and If_, and for every non-name node it built a PhpDocInfo and ran the phpdoc rename, regardless of whether the node had a docblock.

A phpdoc type rename can only ever change a node that carries a real docblock. Plain line comments or no comment never match.

Measurement

Single-process run over this repo's src/ + rules/ with a 600-entry rename map, counting the phpdoc path:

  • createFromNode was called 28258 times (every Expression/If_/FunctionLike/Property/ClassLike node)
  • only 3983 of those nodes actually had a docblock
  • 1576 had plain comments only - these still ran the full refactorPhpDoc, which cannot change anything
  • 22699 had no comment at all

The phpdoc path (createFromNode + refactorPhpDoc) accounted for ~92% of the rule's own time.

Change

  1. Guard the phpdoc branch behind a cheap getDocComment() !== null check. The expensive path now runs on ~4k nodes instead of ~28k. Behaviour is identical: nodes without a docblock produced an empty/typeless PhpDocInfo that refactorPhpDoc always left unchanged.
  2. Drop the per-call serialize() + hash in createOldToNewTypes. The rename map is constant during a run, so memoize on the identical array and remove the now unused FileHasher dependency.

Tests

  • rules-tests/Renaming - 105 tests green
  • ECS + PHPStan level 8 clean on the changed file

TomasVotruba and others added 2 commits October 11, 2026 18:26
…lock

The rule visits Expression, If_, FunctionLike, Property and ClassLike nodes. For every one it built a PhpDocInfo and ran the phpdoc rename, even though only a real docblock can carry a renamable type.

On rector-src src+rules that phpdoc path fired 28k times but only ~4k nodes had a docblock. Guard it with a cheap getDocComment() check so createFromNode and refactorPhpDoc run only when there is a docblock.

Also drop the per-call serialize()+hash in createOldToNewTypes; the rename map is constant during a run, so memoize on the identical array and remove the now unused FileHasher dependency.
@TomasVotruba
TomasVotruba merged commit c97f196 into main Oct 11, 2026
49 checks passed
@TomasVotruba
TomasVotruba deleted the perf-rename-class-skip-nondoc-nodes branch October 11, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants