bug #28889 [Serializer] Reduce class discriminator overhead (fbourigault)

This PR was merged into the 4.1 branch.

Discussion
----------

[Serializer] Reduce class discriminator overhead

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #28537
| License       | MIT
| Doc PR        | N/A

This try to fix the overhead added by class discriminator feature.

Here is a 4.1 vs this PR comparison:
https://blackfire.io/profiles/compare/20ead249-0e98-430f-9b8d-906f464b1854/graph

And a 3.4 vs this PR comparison:
https://blackfire.io/profiles/compare/7e402dde-4a54-4053-a12e-d3d6891afc02/graph

Commits
-------

326c267de2 [Serializer] Reduce class discriminator overhead
This commit is contained in:
Nicolas Grekas 2018-10-20 23:23:03 +02:00
commit f1795c07e6

View File

@ -30,6 +30,8 @@ class ObjectNormalizer extends AbstractObjectNormalizer
{
protected $propertyAccessor;
private $discriminatorCache = array();
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null)
{
if (!\class_exists(PropertyAccess::class)) {
@ -110,15 +112,16 @@ class ObjectNormalizer extends AbstractObjectNormalizer
*/
protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
{
if (null !== $this->classDiscriminatorResolver) {
$mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object);
if (null !== $mapping && $attribute == $mapping->getTypeProperty()) {
return $this->classDiscriminatorResolver->getTypeForMappedObject($object);
$cacheKey = \get_class($object);
if (!array_key_exists($cacheKey, $this->discriminatorCache)) {
$this->discriminatorCache[$cacheKey] = null;
if (null !== $this->classDiscriminatorResolver) {
$mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object);
$this->discriminatorCache[$cacheKey] = null === $mapping ? null : $mapping->getTypeProperty();
}
}
return $this->propertyAccessor->getValue($object, $attribute);
return $attribute === $this->discriminatorCache[$cacheKey] ? $this->classDiscriminatorResolver->getTypeForMappedObject($object) : $this->propertyAccessor->getValue($object, $attribute);
}
/**