Skip to content

Performance: Early return in PhpDocNode refactoring for class renames#3509

Merged
TomasVotruba merged 5 commits intorectorphp:mainfrom
keulinho:improve-class-renamer-doc-node-handling
May 6, 2023
Merged

Performance: Early return in PhpDocNode refactoring for class renames#3509
TomasVotruba merged 5 commits intorectorphp:mainfrom
keulinho:improve-class-renamer-doc-node-handling

Conversation

@keulinho
Copy link
Copy Markdown
Contributor

Another micro optimization bringing ~3% in our case: https://blackfire.io/profiles/compare/92f9a385-14c9-496c-8351-7be1d348e0bf/graph

image

@keulinho keulinho requested a review from TomasVotruba as a code owner March 23, 2023 14:57
Copy link
Copy Markdown
Member

@samsonasik samsonasik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The origNode only be updated after node refactored, so it may be overlapped with "just updated" node.

"origNode" attribute usually used to verify node just reprinted.

I think it should be node, if it broke the test, something may happen in the middle.

@keulinho
Copy link
Copy Markdown
Contributor Author

Using node does not work here, because of your internal caching in \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory::createFromNode

Because there you cache the phpDocInfo by node, even if the node by have changed:

        $objectHash = spl_object_hash($node);
        if (isset($this->phpDocInfosByObjectHash[$objectHash])) {
            return $this->phpDocInfosByObjectHash[$objectHash];
        }

What happened in the case of the failed test was:

  1. the return type of the method was renamed and the doc comment removed
  2. the refactor php doc was called and it was running into the early return because the changed node doesn't have a doc comment anymore, thus the doc comment was removed instead of changed to the new class name

The current implementation in the class renamer relies on the following workflow:

  1. The return type is renamed and doc comment removed
  2. The createFromNodeOrEmpty call returns the phpDocInfo the node had before step 1 (because of the caching)
  3. then the doc comment was correctly changed

As the code currently relies on the underlying caching mechanism i didn't want to change the behaviour of how that all works to much

My current approach here is that when a node did not have a doc comment in the original source code, it also never needs to be refactored so we can do a early return here which is a lot faster, so i think checking the original node is a valid approach

Does that make sense?

@samsonasik
Copy link
Copy Markdown
Member

I will let @TomasVotruba decide on this then

@TomasVotruba
Copy link
Copy Markdown
Member

The code is very hard to read and understand.
I'm sure well remove it in the future, even with comments.

We can improve the performance here, but I'd prefer more clear and self-explanatory code.

@keulinho
Copy link
Copy Markdown
Contributor Author

I clearified the code by extracting the multiple if check to it's own method and gave it a better name and added some explanatory comments

@TomasVotruba
Copy link
Copy Markdown
Member

Thanks for the update, this looks good 👍

@TomasVotruba TomasVotruba merged commit 48e431b into rectorphp:main May 6, 2023
@samsonasik
Copy link
Copy Markdown
Member

@keulinho @TomasVotruba it cause error in latest main tests unfortunatelly, it needs to be reverted

https://github.com/rectorphp/rector-src/actions/runs/4902565356/jobs/8754485599#step:5:78

@TomasVotruba
Copy link
Copy Markdown
Member

I see 👍 Thanks @samsonasik

samsonasik added a commit that referenced this pull request May 6, 2023
samsonasik added a commit that referenced this pull request May 8, 2023
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