Skip to content

Commit

Permalink
Improve lazy ghost performance by avoiding self-referencing closure. (#…
Browse files Browse the repository at this point in the history
…11376)

* Improve lazy ghost performance by avoiding self-referencing closure.

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>

* update baselien

---------

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
  • Loading branch information
beberlei and nicolas-grekas committed Mar 19, 2024
1 parent 40a0964 commit 9d1a497
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 17 deletions.
8 changes: 2 additions & 6 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,7 @@
<code><![CDATA[getValue]]></code>
<code><![CDATA[setAccessible]]></code>
<code><![CDATA[setValue]]></code>
<code><![CDATA[setValue]]></code>
</PossiblyNullReference>
<TypeDoesNotContainType>
<code><![CDATA[$autoGenerate < 0]]></code>
Expand All @@ -1501,13 +1502,8 @@
<code><![CDATA[__wakeup]]></code>
</UndefinedInterfaceMethod>
<UndefinedMethod>
<code><![CDATA[self::createLazyGhost(static function (InternalProxy $object) use ($initializer, &$proxy): void {
$initializer($object, $proxy);
}, $skippedProperties)]]></code>
<code><![CDATA[self::createLazyGhost($initializer, $skippedProperties)]]></code>
</UndefinedMethod>
<UndefinedVariable>
<code><![CDATA[$proxy]]></code>
</UndefinedVariable>
<UnresolvableInclude>
<code><![CDATA[require $fileName]]></code>
</UnresolvableInclude>
Expand Down
14 changes: 6 additions & 8 deletions src/Proxy/ProxyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,11 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister
*/
private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister, IdentifierFlattener $identifierFlattener): Closure
{
return static function (InternalProxy $proxy, InternalProxy $original) use ($entityPersister, $classMetadata, $identifierFlattener): void {
$identifier = $classMetadata->getIdentifierValues($original);
$entity = $entityPersister->loadById($identifier, $original);
return static function (InternalProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener): void {
$identifier = $classMetadata->getIdentifierValues($proxy);
$original = $entityPersister->loadById($identifier);

if ($entity === null) {
if ($original === null) {
throw EntityNotFoundException::fromClassNameAndIdentifier(
$classMetadata->getName(),
$identifierFlattener->flattenIdentifier($classMetadata, $identifier)
Expand All @@ -382,7 +382,7 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi
continue;
}

$property->setValue($proxy, $property->getValue($entity));
$property->setValue($proxy, $property->getValue($original));
}
};
}
Expand Down Expand Up @@ -468,9 +468,7 @@ private function getProxyFactory(string $className): Closure
$identifierFields = array_intersect_key($class->getReflectionProperties(), $identifiers);

$proxyFactory = Closure::bind(static function (array $identifier) use ($initializer, $skippedProperties, $identifierFields, $className): InternalProxy {
$proxy = self::createLazyGhost(static function (InternalProxy $object) use ($initializer, &$proxy): void {
$initializer($object, $proxy);
}, $skippedProperties);
$proxy = self::createLazyGhost($initializer, $skippedProperties);

foreach ($identifierFields as $idField => $reflector) {
if (! isset($identifier[$idField])) {
Expand Down
6 changes: 3 additions & 3 deletions tests/Tests/ORM/Proxy/ProxyFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function testReferenceProxyDelegatesLoadingToThePersister(): void
{
$identifier = ['id' => 42];
$proxyClass = 'Proxies\__CG__\Doctrine\Tests\Models\ECommerce\ECommerceFeature';
$persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load'])
$persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['loadById'])
->disableOriginalConstructor()
->getMock();

Expand All @@ -75,8 +75,8 @@ public function testReferenceProxyDelegatesLoadingToThePersister(): void

$persister
->expects(self::atLeastOnce())
->method('load')
->with(self::equalTo($identifier), self::isInstanceOf($proxyClass))
->method('loadById')
->with(self::equalTo($identifier))
->will(self::returnValue($proxy));

$proxy->getDescription();
Expand Down

0 comments on commit 9d1a497

Please sign in to comment.