From cbcdb8b2d4282b223a4fe88df13e19e85347d3cc Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 7 Feb 2022 11:26:28 +0000 Subject: [PATCH] Issue #3164210 by jungle, sylus, Akhildev.cs, dww: Refactor array_merge() usage in loops as possible for performance --- .../Core/Authentication/AuthenticationCollector.php | 5 +---- core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php | 5 +---- core/lib/Drupal/Core/Config/ConfigManager.php | 4 ++-- core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php | 8 +++++--- .../Drupal/Core/Entity/EntityAccessControlHandler.php | 8 +++++--- core/lib/Drupal/Core/Extension/ModuleHandler.php | 3 ++- core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php | 7 +------ core/lib/Drupal/Core/Logger/LoggerChannel.php | 7 +------ .../Drupal/Core/PathProcessor/PathProcessorManager.php | 7 +------ .../Drupal/Core/RouteProcessor/RouteProcessorManager.php | 7 +------ .../Drupal/Core/StringTranslation/TranslationManager.php | 7 +------ .../src/Controller/ConfigTranslationMapperList.php | 4 +--- .../EntityReference/EntityReferenceAdminTest.php | 4 +++- .../jsonapi/src/Routing/ReadOnlyModeMethodFilter.php | 3 ++- core/modules/locale/locale.bulk.inc | 3 ++- .../src/RegisterEntityResolversCompilerPass.php | 9 +-------- .../src/RegisterSerializationClassesCompilerPass.php | 9 +-------- .../views/src/Plugin/views/field/RenderedEntity.php | 4 ++-- core/modules/views/src/Plugin/views/query/Sql.php | 9 +-------- core/tests/Drupal/KernelTests/AssertContentTrait.php | 4 +++- .../Core/Authentication/AuthenticationCollectorTest.php | 5 +---- 21 files changed, 38 insertions(+), 84 deletions(-) diff --git a/core/lib/Drupal/Core/Authentication/AuthenticationCollector.php b/core/lib/Drupal/Core/Authentication/AuthenticationCollector.php index de6edae00619..3ac54c0a7e76 100644 --- a/core/lib/Drupal/Core/Authentication/AuthenticationCollector.php +++ b/core/lib/Drupal/Core/Authentication/AuthenticationCollector.php @@ -72,10 +72,7 @@ public function getSortedProviders() { krsort($this->providerOrders); // Merge nested providers from $this->providers into $this->sortedProviders. - $this->sortedProviders = []; - foreach ($this->providerOrders as $providers) { - $this->sortedProviders = array_merge($this->sortedProviders, $providers); - } + $this->sortedProviders = array_merge([], ...$this->providerOrders); } return $this->sortedProviders; diff --git a/core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php index f418a5ee2254..c71137b6a34d 100644 --- a/core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php +++ b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php @@ -107,10 +107,7 @@ protected function getSortedBuilders() { // Sort the builders according to priority. krsort($this->builders); // Merge nested builders from $this->builders into $this->sortedBuilders. - $this->sortedBuilders = []; - foreach ($this->builders as $builders) { - $this->sortedBuilders = array_merge($this->sortedBuilders, $builders); - } + $this->sortedBuilders = array_merge([], ...$this->builders); } return $this->sortedBuilders; } diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index 51cbaa505c8f..9790a68c536d 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -264,9 +264,9 @@ public function findConfigEntityDependencies($type, array $names, ConfigDependen } $dependencies = []; foreach ($names as $name) { - $dependencies = array_merge($dependencies, $dependency_manager->getDependentEntities($type, $name)); + $dependencies[] = $dependency_manager->getDependentEntities($type, $name); } - return $dependencies; + return array_merge([], ...$dependencies); } /** diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php index 4e044f96726f..9b94ae80a388 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php @@ -58,8 +58,9 @@ public function checkConfigSchema(TypedConfigManagerInterface $typed_config, $co $this->schema = $typed_config->createFromNameAndData($config_name, $config_data); $errors = []; foreach ($config_data as $key => $value) { - $errors = array_merge($errors, $this->checkValue($key, $value)); + $errors[] = $this->checkValue($key, $value); } + $errors = array_merge([], ...$errors); if (empty($errors)) { return TRUE; } @@ -130,11 +131,12 @@ protected function checkValue($key, $value) { if (!is_array($value)) { $value = (array) $value; } + $nested_errors = []; // Recurse into any nested keys. foreach ($value as $nested_value_key => $nested_value) { - $errors = array_merge($errors, $this->checkValue($key . '.' . $nested_value_key, $nested_value)); + $nested_errors[] = $this->checkValue($key . '.' . $nested_value_key, $nested_value); } - return $errors; + return array_merge($errors, ...$nested_errors); } // No errors found. return []; diff --git a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php index 0e02f9536ab3..b6b39c382267 100644 --- a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php +++ b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php @@ -340,12 +340,14 @@ public function fieldAccess($operation, FieldDefinitionInterface $field_definiti $default = $default->andIf($entity_default); // Invoke hook and collect grants/denies for field access from other - // modules. Our default access flag is masked under the ':default' key. - $grants = [':default' => $default]; + // modules. + $grants = []; $hook_implementations = $this->moduleHandler()->getImplementations('entity_field_access'); foreach ($hook_implementations as $module) { - $grants = array_merge($grants, [$module => $this->moduleHandler()->invoke($module, 'entity_field_access', [$operation, $field_definition, $account, $items])]); + $grants[] = [$module => $this->moduleHandler()->invoke($module, 'entity_field_access', [$operation, $field_definition, $account, $items])]; } + // Our default access flag is masked under the ':default' key. + $grants = array_merge([':default' => $default], ...$grants); // Also allow modules to alter the returned grants/denies. $context = [ diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 1b22117ae227..6a84fa576be1 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -492,8 +492,9 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) { // implements at least one of them. $extra_modules = []; foreach ($extra_types as $extra_type) { - $extra_modules = array_merge($extra_modules, $this->getImplementations($extra_type . '_alter')); + $extra_modules[] = $this->getImplementations($extra_type . '_alter'); } + $extra_modules = array_merge([], ...$extra_modules); // If any modules implement one of the extra hooks that do not implement // the primary hook, we need to add them to the $modules array in their // appropriate order. $this->getImplementations() can only return diff --git a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php index 07ffec91dd38..172f13ff62c5 100644 --- a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php +++ b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php @@ -107,13 +107,8 @@ public function isGuesserSupported(): bool { * A sorted array of MIME type guesser objects. */ protected function sortGuessers() { - $sorted = []; krsort($this->guessers); - - foreach ($this->guessers as $guesser) { - $sorted = array_merge($sorted, $guesser); - } - return $sorted; + return array_merge([], ...$this->guessers); } } diff --git a/core/lib/Drupal/Core/Logger/LoggerChannel.php b/core/lib/Drupal/Core/Logger/LoggerChannel.php index 13dff9ce38c6..97aae2b858cc 100644 --- a/core/lib/Drupal/Core/Logger/LoggerChannel.php +++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php @@ -165,13 +165,8 @@ public function addLogger(LoggerInterface $logger, $priority = 0) { * An array of sorted loggers by priority. */ protected function sortLoggers() { - $sorted = []; krsort($this->loggers); - - foreach ($this->loggers as $loggers) { - $sorted = array_merge($sorted, $loggers); - } - return $sorted; + return array_merge([], ...$this->loggers); } } diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php index 55a952213adb..b4e8fac7f03e 100644 --- a/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php +++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php @@ -131,13 +131,8 @@ protected function getOutbound() { * The processor type to sort, e.g. 'inboundProcessors'. */ protected function sortProcessors($type) { - $sorted = []; krsort($this->{$type}); - - foreach ($this->{$type} as $processors) { - $sorted = array_merge($sorted, $processors); - } - return $sorted; + return array_merge([], ...$this->{$type}); } } diff --git a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorManager.php b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorManager.php index 74a791dfbdb7..65a358769e04 100644 --- a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorManager.php +++ b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorManager.php @@ -71,13 +71,8 @@ protected function getOutbound() { * Sorts the processors according to priority. */ protected function sortProcessors() { - $sorted = []; krsort($this->outboundProcessors); - - foreach ($this->outboundProcessors as $processors) { - $sorted = array_merge($sorted, $processors); - } - return $sorted; + return array_merge([], ...$this->outboundProcessors); } } diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php index 40bf8f4b31db..a9e42778b14c 100644 --- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php +++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php @@ -77,13 +77,8 @@ public function addTranslator(TranslatorInterface $translator, $priority = 0) { * A sorted array of translator objects. */ protected function sortTranslators() { - $sorted = []; krsort($this->translators); - - foreach ($this->translators as $translators) { - $sorted = array_merge($sorted, $translators); - } - return $sorted; + return array_merge([], ...$this->translators); } /** diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationMapperList.php b/core/modules/config_translation/src/Controller/ConfigTranslationMapperList.php index 0d612a7a356a..cc06c4682eb4 100644 --- a/core/modules/config_translation/src/Controller/ConfigTranslationMapperList.php +++ b/core/modules/config_translation/src/Controller/ConfigTranslationMapperList.php @@ -71,9 +71,7 @@ public function render() { $mappers[$weight] = $mapper; } - foreach ($mappers as $mapper) { - $build['#rows'] = array_merge($build['#rows'], $mapper); - } + $build['#rows'] = array_merge([], ...$mappers); return $build; } diff --git a/core/modules/field/tests/src/FunctionalJavascript/EntityReference/EntityReferenceAdminTest.php b/core/modules/field/tests/src/FunctionalJavascript/EntityReference/EntityReferenceAdminTest.php index f19f4ed37c41..6b057cbc8922 100644 --- a/core/modules/field/tests/src/FunctionalJavascript/EntityReference/EntityReferenceAdminTest.php +++ b/core/modules/field/tests/src/FunctionalJavascript/EntityReference/EntityReferenceAdminTest.php @@ -359,9 +359,11 @@ protected function assertFieldSelectOptions(string $name, array $expected_option $field = $this->assertSession()->selectExists($name); $options = $field->findAll('xpath', 'option'); $optgroups = $field->findAll('xpath', 'optgroup'); + $nested_options = []; foreach ($optgroups as $optgroup) { - $options = array_merge($options, $optgroup->findAll('xpath', 'option')); + $nested_options[] = $optgroup->findAll('xpath', 'option'); } + $options = array_merge($options, ...$nested_options); array_walk($options, function (NodeElement &$option) { $option = $option->getAttribute('value'); }); diff --git a/core/modules/jsonapi/src/Routing/ReadOnlyModeMethodFilter.php b/core/modules/jsonapi/src/Routing/ReadOnlyModeMethodFilter.php index f8266217a8fd..c4e6c24eb871 100644 --- a/core/modules/jsonapi/src/Routing/ReadOnlyModeMethodFilter.php +++ b/core/modules/jsonapi/src/Routing/ReadOnlyModeMethodFilter.php @@ -47,9 +47,10 @@ public function __construct(FilterInterface $inner, ConfigFactoryInterface $conf public function filter(RouteCollection $collection, Request $request) { $all_supported_methods = []; foreach ($collection->all() as $name => $route) { - $all_supported_methods = array_merge($all_supported_methods, $route->getMethods()); + $all_supported_methods[] = $route->getMethods(); } + $all_supported_methods = array_merge([], ...$all_supported_methods); $collection = $this->inner->filter($collection, $request); if (!$this->readOnlyModeIsEnabled) { diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc index d4a68e0bf00e..611d44b85d66 100644 --- a/core/modules/locale/locale.bulk.inc +++ b/core/modules/locale/locale.bulk.inc @@ -305,8 +305,9 @@ function locale_translate_batch_refresh(&$context) { // Get list of unique string identifiers and language codes updated. $langcodes = array_unique(array_values($context['results']['languages'])); foreach ($context['results']['stats'] as $report) { - $strings = array_merge($strings, $report['strings']); + $strings[] = $report['strings']; } + $strings = array_merge([], ...$strings); } if ($strings) { // Initialize multi-step string refresh. diff --git a/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php b/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php index 2e61158dda35..c3bb1d11a9ae 100644 --- a/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php +++ b/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php @@ -48,15 +48,8 @@ public function process(ContainerBuilder $container) { * to low priority. */ protected function sort($services) { - $sorted = []; krsort($services); - - // Flatten the array. - foreach ($services as $a) { - $sorted = array_merge($sorted, $a); - } - - return $sorted; + return array_merge([], ...$services); } } diff --git a/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php b/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php index 3071c59d606f..02c7fa600f6f 100644 --- a/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php +++ b/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php @@ -74,15 +74,8 @@ public function process(ContainerBuilder $container) { * to low priority. */ protected function sort($services) { - $sorted = []; krsort($services); - - // Flatten the array. - foreach ($services as $a) { - $sorted = array_merge($sorted, $a); - } - - return $sorted; + return array_merge([], ...$services); } } diff --git a/core/modules/views/src/Plugin/views/field/RenderedEntity.php b/core/modules/views/src/Plugin/views/field/RenderedEntity.php index 5dd494805378..dce5efcd219d 100644 --- a/core/modules/views/src/Plugin/views/field/RenderedEntity.php +++ b/core/modules/views/src/Plugin/views/field/RenderedEntity.php @@ -161,9 +161,9 @@ public function getCacheTags() { $tags = []; foreach ($view_displays as $view_display) { - $tags = array_merge($tags, $view_display->getCacheTags()); + $tags[] = $view_display->getCacheTags(); } - return $tags; + return array_merge([], ...$tags); } /** diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php index 978d5fe116ca..3c584ba9761d 100644 --- a/core/modules/views/src/Plugin/views/query/Sql.php +++ b/core/modules/views/src/Plugin/views/query/Sql.php @@ -1422,14 +1422,7 @@ public function query($get_count = FALSE) { * Get the arguments attached to the WHERE and HAVING clauses of this query. */ public function getWhereArgs() { - $args = []; - foreach ($this->where as $where) { - $args = array_merge($args, $where['args']); - } - foreach ($this->having as $having) { - $args = array_merge($args, $having['args']); - } - return $args; + return array_merge([], ...array_column($this->where, 'args'), ...array_column($this->having, 'args')); } /** diff --git a/core/tests/Drupal/KernelTests/AssertContentTrait.php b/core/tests/Drupal/KernelTests/AssertContentTrait.php index a76d357ea4a3..f8a99a0ce477 100644 --- a/core/tests/Drupal/KernelTests/AssertContentTrait.php +++ b/core/tests/Drupal/KernelTests/AssertContentTrait.php @@ -264,9 +264,11 @@ protected function getAllOptions(\SimpleXMLElement $element) { // Search option group children. if (isset($element->optgroup)) { + $nested_options = []; foreach ($element->optgroup as $group) { - $options = array_merge($options, $this->getAllOptions($group)); + $nested_options[] = $this->getAllOptions($group); } + $options = array_merge($options, ...$nested_options); } return $options; } diff --git a/core/tests/Drupal/Tests/Core/Authentication/AuthenticationCollectorTest.php b/core/tests/Drupal/Tests/Core/Authentication/AuthenticationCollectorTest.php index 609f4f30f941..6e72d8901dbf 100644 --- a/core/tests/Drupal/Tests/Core/Authentication/AuthenticationCollectorTest.php +++ b/core/tests/Drupal/Tests/Core/Authentication/AuthenticationCollectorTest.php @@ -43,10 +43,7 @@ public function testAuthenticationCollector() { krsort($providers); // Merge nested providers from $providers into $sorted_providers. - $sorted_providers = []; - foreach ($providers as $providers_priority) { - $sorted_providers = array_merge($sorted_providers, $providers_priority); - } + $sorted_providers = array_merge([], ...$providers); $this->assertEquals($sorted_providers, $authentication_collector->getSortedProviders()); // Test AuthenticationCollector::getProvider() and -- GitLab