- Issue created by @mxr576
- 🇭🇺Hungary mxr576 Hungary
Based on my investigation into the performance regression, I've identified several contributing factors to the slowness in Recipe Kernel tests:
Both Functional and Kernel tests use
MemoryCacheFactory
as the default cache factory, but Kernel tests appear to be disproportionately impacted by its non-persistent nature. The frequent cache invalidations during module installation compound this issue.Related to 📌 RecipeRunner::processInstall() installs modules one by one Active - every module installation triggers multiple cache invalidations. Even when replacing the cache factory with a persistent one in Kernel tests, there's no significant performance improvement due to this cache churn.
Attempted mitigation in our Kernel test:
public function register(ContainerBuilder $container) { parent::register($container); // Change container to database cache backends. $container ->register('cache_factory', 'Drupal\Core\Cache\CacheFactory') ->addArgument(new Reference('settings')) ->addMethodCall('setContainer', [new Reference('service_container')]); }
XHProf profiling reveals that attribute discovery is the most time-consuming operation during Recipe Kernel tests:
- Majority of calls to
getDefinitions()
are pass-through calls fromAttributeDiscoveryWithAnnotations::getDefinitions()
- 80% of these calls originate from
DerivativeDiscoveryDecorator::getDefinitions()
- 80% of those calls come from
DefaultPluginManager::findDefinitions()
- Majority of calls to
- 🇭🇺Hungary mxr576 Hungary
For a more realistic comparison, I have removed idempotency check - so the second recipe application - from the GenericRecipeTestBase classes and captured the following with XHGui:
web/core/recipes/standard/tests/src/Kernel/GenericTest.php
web/core/recipes/standard/tests/src/Functional/GenericTest.php