{"action":"created","issue":{"url":"https://api.github.com/repos/symfony/symfony/issues/16294","labels_url":"https://api.github.com/repos/symfony/symfony/issues/16294/labels{/name}","comments_url":"https://api.github.com/repos/symfony/symfony/issues/16294/comments","events_url":"https://api.github.com/repos/symfony/symfony/issues/16294/events","html_url":"https://github.com/symfony/symfony/pull/16294","id":112319337,"number":16294,"title":"[PropertyAccess] Major performance improvement","user":{"login":"dunglas","id":57224,"avatar_url":"https://avatars.githubusercontent.com/u/57224?v=3","gravatar_id":"","url":"https://api.github.com/users/dunglas","html_url":"https://github.com/dunglas","followers_url":"https://api.github.com/users/dunglas/followers","following_url":"https://api.github.com/users/dunglas/following{/other_user}","gists_url":"https://api.github.com/users/dunglas/gists{/gist_id}","starred_url":"https://api.github.com/users/dunglas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dunglas/subscriptions","organizations_url":"https://api.github.com/users/dunglas/orgs","repos_url":"https://api.github.com/users/dunglas/repos","events_url":"https://api.github.com/users/dunglas/events{/privacy}","received_events_url":"https://api.github.com/users/dunglas/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/symfony/symfony/labels/Status:%20Needs%20Review","name":"Status: Needs Review","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-10-20T09:03:08Z","updated_at":"2015-10-20T10:03:02Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/symfony/symfony/pulls/16294","html_url":"https://github.com/symfony/symfony/pull/16294","diff_url":"https://github.com/symfony/symfony/pull/16294.diff","patch_url":"https://github.com/symfony/symfony/pull/16294.patch"},"body":"| Q             | A\r\n| ------------- | ---\r\n| Bug fix?      | yes\r\n| New feature?  | no\r\n| BC breaks?    | no\r\n| Deprecations? | no\r\n| Tests pass?   | yes\r\n| Fixed tickets | #16179\r\n| License       | MIT\r\n| Doc PR        | n/a\r\n\r\nThis PR improves performance of the PropertyAccess component of ~70%.\r\n\r\nThe two main changes are:\r\n\r\n* caching the `PropertyPath` initialization\r\n* caching the guessed access strategy\r\n\r\nThis is especially important for the `ObjectNormalizer` (Symfony Serializer) and the JSON-LD normalizer ([API Platform](https://api-platform.com)) because they use the `PropertyAccessor` class in large loops (ex: normalization of a list of entities).\r\n\r\nHere is the Blackfire comparison: https://blackfire.io/profiles/compare/c42fd275-2b0c-4ce5-8bf3-84762054d31e/graph\r\n\r\nThe code of the benchmark I've used (with Symfony 2.3 as dependency):\r\n\r\n```php\r\n<?php\r\n\r\nrequire 'vendor/autoload.php';\r\n\r\nclass Foo\r\n{\r\n    private $baz;\r\n    public $bar;\r\n\r\n\r\n    public function getBaz()\r\n    {\r\n        return $this->baz;\r\n    }\r\n\r\n    public function setBaz($baz)\r\n    {\r\n        $this->baz = $baz;\r\n    }\r\n}\r\n\r\nuse Symfony\\Component\\PropertyAccess\\PropertyAccess;\r\n\r\n$accessor = PropertyAccess::createPropertyAccessor();\r\n\r\n$start = microtime(true);\r\n\r\nfor ($i = 0; $i < 10000; ++$i) {\r\n    $foo = new Foo();\r\n    $accessor->setValue($foo, 'bar', 'Lorem');\r\n    $accessor->setValue($foo, 'baz', 'Ipsum');\r\n    $accessor->getValue($foo, 'bar');\r\n    $accessor->getValue($foo, 'baz');\r\n}\r\n\r\necho 'Time: '.(microtime(true) - $start).PHP_EOL;\r\n```\r\n\r\nThis PR also adds an optional support for Doctrine cache to keep access information across requests and improve the overall application performance (even outside of loops)."},"comment":{"url":"https://api.github.com/repos/symfony/symfony/issues/comments/149505097","html_url":"https://github.com/symfony/symfony/pull/16294#issuecomment-149505097","issue_url":"https://api.github.com/repos/symfony/symfony/issues/16294","id":149505097,"user":{"login":"sescandell","id":1559970,"avatar_url":"https://avatars.githubusercontent.com/u/1559970?v=3","gravatar_id":"","url":"https://api.github.com/users/sescandell","html_url":"https://github.com/sescandell","followers_url":"https://api.github.com/users/sescandell/followers","following_url":"https://api.github.com/users/sescandell/following{/other_user}","gists_url":"https://api.github.com/users/sescandell/gists{/gist_id}","starred_url":"https://api.github.com/users/sescandell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sescandell/subscriptions","organizations_url":"https://api.github.com/users/sescandell/orgs","repos_url":"https://api.github.com/users/sescandell/repos","events_url":"https://api.github.com/users/sescandell/events{/privacy}","received_events_url":"https://api.github.com/users/sescandell/received_events","type":"User","site_admin":false},"created_at":"2015-10-20T10:03:02Z","updated_at":"2015-10-20T10:03:02Z","body":"Hi,\r\n\r\nIMO, your benchmarks is not exhaustive. What about performance impact on \"non-similar\" objects?\r\n\r\nIf I remember well, form component is mainly based on PropertyPath one.\r\nAssuming a very long form (I remember a PR about form performance improvement in that situation) with many fields, what would be the impact of these changes caching objects for \"nothing\"?\r\n\r\nYour benchmark perfectly feet for scenarios you described (Serialization), but PropertyPath might be used somewhere else.\r\n"}}