Skip to content

[Serializer] AbstractObjectNormalizer deserialization performance #28276

@martiis

Description

@martiis

Symfony version(s) affected: 4.1.3 (havent test other)

Description
I have noticed that deserialiation performance arent as good as serialization, but f.e. jms serializer serialization/deserialization perform roughly the same.

My test is deserializing 1000 objects with various scalar value properies + one property is an object + one property holds 5-15 small objects in array.

Deserialization took about 300 ms while serialization is about 150 ms (xdebug disabled)

How to reproduce
My actual test https://github.com/martiis/symfony-serialization-bench/blob/master/src/Command/BenchSymfonySerializerCommand.php#L78

Possible Solution
Based on blackfire lots of calls are being made to resolve class attribute type here even if it has done it before. So I tried to cache resolved types to a local variable and lost about 100ms from the test.

My changed method:

    private function getTypes(string $currentClass, string $attribute)
    {
        if (null === $this->propertyTypeExtractor) {
            return null;
        }

        $key = $currentClass . ':' . $attribute;
        if (isset($this->loadedTypes[$key])) {
            return $this->loadedTypes[$key];
        }

        if (null !== $types = $this->propertyTypeExtractor->getTypes($currentClass, $attribute)) {
            return $this->loadedTypes[$key] = $types;
        }

        if (null !== $this->classDiscriminatorResolver && null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForClass($currentClass)) {
            if ($discriminatorMapping->getTypeProperty() === $attribute) {
                return $this->loadedTypes[$key] = array(
                    new Type(Type::BUILTIN_TYPE_STRING),
                );
            }

            foreach ($discriminatorMapping->getTypesMapping() as $mappedClass) {
                if (null !== $types = $this->propertyTypeExtractor->getTypes($mappedClass, $attribute)) {
                    return $this->loadedTypes[$key] = $types;
                }
            }
        }

        return $this->loadedTypes[$key] = null;
    } 

Additional context

Blackfire graph before
Blackfire graph after

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions