-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Speed up ObjectNormalizer by introducing ObjectPropertyAccessorInterface #29405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t it possible to use the same method names, and to make PropertyAccessorInterface extending the new one?
If you mean |
src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
Outdated
Show resolved
Hide resolved
I rebased and quoted the placeholders. I would like to have feedback from |
👍 on my side |
self::VALUE => $object, | ||
]; | ||
|
||
return $this->readProperty($zval, $property)[self::VALUE]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fbourigault i am not sure with this. But why is here no catch unlike in case of setPropertyValue ?
Both can throw and have invalid arguments...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am curious if we really need to implement a new interface or if we couldn't improve the existing implementation instead.
@fbourigault Could you do me a favour and create a Blackfire comparison with what I propose in #29999?
@@ -32,14 +34,22 @@ class ObjectNormalizer extends AbstractObjectNormalizer | |||
|
|||
private $discriminatorCache = []; | |||
|
|||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = []) | |||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = []) | |||
{ | |||
if (!\class_exists(PropertyAccess::class)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this check be moved down a bit now as the PropertyAccess component is not necessarily needed anymore?
} | ||
|
||
if (null !== $propertyAccessor && !$propertyAccessor instanceof ObjectPropertyAccessorInterface) { | ||
@trigger_error(sprintf('Passing an instance of "%s" as the 3rd argument to "%s()" is deprecated since Symfony 4.3. Pass a "%s" instance instead.', PropertyAccessorInterface::class, __METHOD__, ObjectPropertyAccessorInterface::class), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would reword this a bit to read like this:
@trigger_error(sprintf('Passing a "%s" implementation as the 3rd argument to "%s()" that does not implement "%s" is deprecated since Symfony 4.3.', PropertyAccessorInterface::class, ObjectPropertyAccessorInterface::class, __METHOD__), E_USER_DEPRECATED);
Here is the benchmark : https://blackfire.io/profiles/compare/39387d7e-811c-4d42-af3a-c06fb0f13c38/graph @xabbuh I like your performance improvement proposal. |
@fbourigault Thank you very much! 👍 |
Are you sure that's the right URL? The profile still references the |
The comparison is about this PR vs #29999. |
Makes sense 👍 Can you also post a link to the comparison of the |
Closing as #29999 is a better solution. |
…(xabbuh) This PR was merged into the 4.3-dev branch. Discussion ---------- [PropertyAccess] speed up accessing object properties | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #28926, #29405 | License | MIT | Doc PR | I propose to improve the performance of the `ObjectNormalizer` by not adding a new interface to the PropertyAccess component, but by adding some shortcut for cases where we know that we do not need to perform all checks. The added benefit is that this will not only speed up the `ObjectNormalizer` class, but will be available for every consumer of the `PropertyAccessor` without having to adapt to a new API. TODO: - [ ] confirm that these changes indeed introduce the same benefit as #29405 doing an actual benchmark Commits ------- ef7876e speed up accessing object properties
The main goal of this PR is to speed up the
ObjectNormalizer
. It's a simpler implementation of #28926 which does not change anyPropertyAccessor
internals.The performance boost depends on the size of the graph. The larger the graph is, bigger the performance boost is.
Here is some bench created using https://github.com/php-serializers/ivory-serializer-benchmark. The numbers in parenthesis are the horizontal and vertical complexity used when profiling.
To do
PropertyAccessor::getPropertyValue
tests.PropertyAccessor::setPropertyValue
tests.UPGRADE-4.3.md
.UPGRADE-5.0.md
.src/Component/PropertyAccess/CHANGELOG.md
.src/Component/Serializer/CHANGELOG.md
.