Skip to content

Commit 07273df

Browse files
committed
feature symfony#61497 [ObjectMapper] cache attributes in memory (soyuka)
This PR was submitted for the 7.3 branch but it was squashed and merged into the 7.4 branch instead. Discussion ---------- [ObjectMapper] cache attributes in memory | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | na | License | MIT Profile: <img width="1254" height="262" alt="20250821_22h15m27s_grim" src="https://github.com/user-attachments/assets/bf88422e-e01d-4768-aa1c-fdaa4dc87c38" /> <img width="1263" height="309" alt="20250821_22h15m12s_grim" src="https://github.com/user-attachments/assets/cd50f59d-7302-4cc0-8a25-2659922e0e89" /> <details> <summary>phpbench</summary> ```php <?php namespace Symfony\Component\ObjectMapper\Benchmarks; use PhpBench\Attributes as Bench; use Symfony\Component\ObjectMapper\ObjectMapper; use Symfony\Component\ObjectMapper\Tests\Fixtures\A; use Symfony\Component\ObjectMapper\Tests\Fixtures\C; use Symfony\Component\ObjectMapper\Tests\Fixtures\D; #[Bench\BeforeMethods('setUp')] class ObjectMapperBench { private ObjectMapper $objectMapper; private A $sourceObject; public function setUp(): void { $this->objectMapper = new ObjectMapper(); $d = new D(baz: 'foo', bat: 'bar'); $c = new C(foo: 'foo', bar: 'bar'); $this->sourceObject = new A(); $this->sourceObject->foo = 'test'; $this->sourceObject->transform = 'test'; $this->sourceObject->baz = 'me'; $this->sourceObject->notinb = 'test'; $this->sourceObject->relation = $c; $this->sourceObject->relationNotMapped = $d; } #[Bench\Revs(100)] #[Bench\Iterations(5)] public function benchObjectMapper(): void { $this->objectMapper->map($this->sourceObject); } } ``` </details> Commits ------- 3576a57 [ObjectMapper] cache attributes in memory
2 parents c228caa + 3576a57 commit 07273df

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/Symfony/Component/ObjectMapper/Metadata/ReflectionObjectMapperMetadataFactory.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@
2121
*/
2222
final class ReflectionObjectMapperMetadataFactory implements ObjectMapperMetadataFactoryInterface
2323
{
24+
private array $reflectionClassCache = [];
25+
private array $attributesCache = [];
26+
2427
public function create(object $object, ?string $property = null, array $context = []): array
2528
{
2629
try {
27-
$refl = new \ReflectionClass($object);
28-
$mapTo = [];
29-
foreach (($property ? $refl->getProperty($property) : $refl)->getAttributes(Map::class, \ReflectionAttribute::IS_INSTANCEOF) as $mapAttribute) {
30-
$map = $mapAttribute->newInstance();
31-
$mapTo[] = new Mapping($map->target, $map->source, $map->if, $map->transform);
30+
$key = $object::class.($property ?? '');
31+
32+
if (isset($this->attributesCache[$key])) {
33+
return $this->attributesCache[$key];
34+
}
35+
36+
$refl = $this->reflectionClassCache[$object::class] ??= new \ReflectionClass($object);
37+
$attributes = ($property ? $refl->getProperty($property) : $refl)->getAttributes(Map::class, \ReflectionAttribute::IS_INSTANCEOF);
38+
$mappings = [];
39+
foreach ($attributes as $attribute) {
40+
$map = $attribute->newInstance();
41+
$mappings[] = new Mapping($map->target, $map->source, $map->if, $map->transform);
3242
}
3343

34-
return $mapTo;
44+
return $this->attributesCache[$key] = $mappings;
3545
} catch (\ReflectionException $e) {
3646
throw new MappingException($e->getMessage(), $e->getCode(), $e);
3747
}

0 commit comments

Comments
 (0)