Core: [performance] Add local cache on ResourceClassResolver::getResourceClass()

Created on 19 Dec 2019  路  2Comments  路  Source: api-platform/core

API Platform version(s) affected: 4.5.*

Description
Follow up of this closed ticket: https://github.com/api-platform/core/issues/1068, I find a way to optimize a lot ResourceClassResolver::getResourceClass().

How to reproduce
Just go to a normal apip route. My case is violent because I've a lot of api resources and the response returns a lot of entities.

But there is room for improvment!

Possible Solution
ResourceClassResolver::getResourceClass()聽is responsible of no less than 13% in prod mode, because foreach entity, it will go through ALL possible resource, without any break in the loop (seems logic) nor any cache. And so, is_a is called 63630 times.

Just adding a local cache clear everything:

        if (isset($this->localMostSpecificResourceClassCache[$targetClass])) {
            return $this->localMostSpecificResourceClassCache[$targetClass];
        }

        foreach ($this->resourceNameCollectionFactory->create() as $resourceClassName) {
            if (!is_a($targetClass, $resourceClassName, true)) {
                continue;
            }

            if (null === $mostSpecificResourceClass || is_subclass_of($resourceClassName, $mostSpecificResourceClass)) {
                $mostSpecificResourceClass = $resourceClassName;
            }
        }

        if (null === $mostSpecificResourceClass) {
            throw new \LogicException('Unexpected execution flow.');
        }

        $this->localMostSpecificResourceClassCache[$targetClass] = $mostSpecificResourceClass;

Before :

image

Diff :

image

performance

Most helpful comment

If someones asks for the apcu_fetch, I created an issue for that: https://github.com/symfony/symfony/issues/35041

All 2 comments

If someones asks for the apcu_fetch, I created an issue for that: https://github.com/symfony/symfony/issues/35041

LGTM!

Was this page helpful?
0 / 5 - 0 ratings