Audit usages of cache.static

Created on 28 November 2018, about 6 years ago
Updated 16 November 2023, about 1 year ago

Problem/Motivation

During performance auditing and testing in jsonapi module's issue #3014232: [regression] ResourceTypeRepository is significantly slower in JSON:API 2, becomes noticeable when handling hundreds of interlinked resources it turned out that the cache service cache.static is much slower than using native PHP private variables. mainly caused by the internal serialize on cache set and unserialize on EVERY cache get. In that particular issue the speed-up was around 60% of total request time. and the actual slow method that this was happening from 6 seconds to 30 mili-seconds. (around 200 times).

It turned out that the internal implementation used for static caches namly the cache.static service is \Drupal\Core\Cache\MemoryBackend and it's MUCH slower than the other available one \Drupal\Core\Cache\MemoryCache\MemoryCache

Proposed resolution

Change the factory and use the faster memory cache implementation internally by default or introduce a new service that could utilize that as easy as the cache.static, but to use the faster implementation.

Remaining tasks

Discussion, patch etc.

User interface changes

None expected - tweaks in cache internals.

API changes

TBD.

Data model changes

None expected (cache tweaks).

Release notes snippet

TBD.

📌 Task
Status

Needs work

Version

11.0 🔥

Component
Cache 

Last updated 13 minutes ago

Created by

🇧🇬Bulgaria ndobromirov

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    run-tests.sh fatal error
  • 🇩🇪Germany geek-merlin Freiburg, Germany

    Intereting! Doing the most bold approach to see what happens. NR only for the bot.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    Build Successful
  • 🇩🇪Germany geek-merlin Freiburg, Germany

    No we only have to swap out the default backend.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    29,263 pass, 4 fail
  • 🇩🇪Germany geek-merlin Freiburg, Germany

    Try replace serialize w/ clone (+remove tag sort), to see what breaks.

  • Status changed to Needs work over 1 year ago
  • 🇩🇪Germany geek-merlin Freiburg, Germany

    So it looks like:
    - The originating issue found that cache.static is 3x slower than static class property caching (which is not tags aware) for some entity structures with many related objects. Fix was to use entity.memory_cache which does NOT serialize.
    - Core since 8.6 uses entity.memory_cache, likely for same reasons
    - The difference is, that cache.static does serialize and you get out a new built data object that is an exact copy of what you put in. The entity.memory_cache otoh gives you the same object, and if it was changed in the meantime, you get that changed version.

    IF more optimizations are needed here, i can only imagine one route:
    - Use https://github.com/myclabs/DeepCopy. And maybe we need / profit from a deep-clone-filter that takes __sleep / __serialize (and thus DependencySerializationTrait) into account.

    I think i'm done here.

  • 🇬🇧United Kingdom catch

    These should never have been added in the way they were IMO, but also probably predate the availability of MemoryCache as distinct from MemoryBackend.

    Is there a reason not to use MemoryBackend instead of cache.static in the backend chain? I would think that would work.

Production build 0.71.5 2024