Skip to content

Commit 541c9d7

Browse files
DI Compile - Performance fixes
General performance optimizations in DI Compile: - move array_merge() out of loop - get rid of in_array usage - optimize string concatenation - use '===' instead of '=='
1 parent db0dce6 commit 541c9d7

File tree

6 files changed

+58
-47
lines changed

6 files changed

+58
-47
lines changed

setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function getList($path)
9494
*/
9595
private function extract(\RecursiveIteratorIterator $recursiveIterator)
9696
{
97-
$classes = [];
97+
$classes = [[]];
9898
foreach ($recursiveIterator as $fileItem) {
9999
/** @var $fileItem \SplFileInfo */
100100
if ($fileItem->isDir() || $fileItem->getExtension() !== 'php' || $fileItem->getBasename()[0] == '.') {
@@ -109,9 +109,9 @@ private function extract(\RecursiveIteratorIterator $recursiveIterator)
109109
$fileScanner = new FileClassScanner($fileItemPath);
110110
$classNames = $fileScanner->getClassNames();
111111
$this->includeClasses($classNames, $fileItemPath);
112-
$classes = array_merge($classes, $classNames);
112+
$classes [] = $classNames;
113113
}
114-
return $classes;
114+
return array_merge(...$classes);
115115
}
116116

117117
/**

setup/src/Magento/Setup/Module/Di/Code/Reader/FileClassScanner.php

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88

99
class FileClassScanner
1010
{
11+
private const NAMESPACE_TOKENS = [
12+
T_WHITESPACE => true,
13+
T_STRING => true,
14+
T_NS_SEPARATOR => true
15+
];
16+
17+
private const ALLOWED_OPEN_BRACES_TOKENS = [
18+
T_CURLY_OPEN => true,
19+
T_DOLLAR_OPEN_CURLY_BRACES => true,
20+
T_STRING_VARNAME => true];
21+
1122
/**
1223
* The filename of the file to introspect
1324
*
@@ -69,9 +80,8 @@ public function getFileContents()
6980
*/
7081
private function extract()
7182
{
72-
$allowedOpenBraces = [T_CURLY_OPEN, T_DOLLAR_OPEN_CURLY_BRACES, T_STRING_VARNAME];
7383
$classes = [];
74-
$namespace = '';
84+
$namespaceParts = [];
7585
$class = '';
7686
$triggerClass = false;
7787
$triggerNamespace = false;
@@ -80,24 +90,25 @@ private function extract()
8090

8191
$this->tokens = token_get_all($this->getFileContents());
8292
foreach ($this->tokens as $index => $token) {
93+
$tokenIsArray = is_array($token);
8394
// Is either a literal brace or an interpolated brace with a variable
84-
if ($token == '{' || (is_array($token) && in_array($token[0], $allowedOpenBraces))) {
95+
if ($token === '{' || ($tokenIsArray && isset(self::ALLOWED_OPEN_BRACES_TOKENS[$token[0]]))) {
8596
$braceLevel++;
86-
} else if ($token == '}') {
97+
} else if ($token === '}') {
8798
$braceLevel--;
8899
}
89100
// The namespace keyword was found in the last loop
90101
if ($triggerNamespace) {
91102
// A string ; or a discovered namespace that looks like "namespace name { }"
92-
if (!is_array($token) || ($namespace && $token[0] == T_WHITESPACE)) {
103+
if (!$tokenIsArray || ($namespaceParts && $token[0] === T_WHITESPACE)) {
93104
$triggerNamespace = false;
94-
$namespace .= '\\';
105+
$namespaceParts[] = '\\';
95106
continue;
96107
}
97-
$namespace .= $token[1];
108+
$namespaceParts[] = $token[1];
98109

99110
// The class keyword was found in the last loop
100-
} else if ($triggerClass && $token[0] == T_STRING) {
111+
} else if ($triggerClass && $token[0] === T_STRING) {
101112
$triggerClass = false;
102113
$class = $token[1];
103114
}
@@ -106,7 +117,7 @@ private function extract()
106117
case T_NAMESPACE:
107118
// Current loop contains the namespace keyword. Between this and the semicolon is the namespace
108119
$triggerNamespace = true;
109-
$namespace = '';
120+
$namespaceParts = [];
110121
$bracedNamespace = $this->isBracedNamespace($index);
111122
break;
112123
case T_CLASS:
@@ -118,9 +129,8 @@ private function extract()
118129
}
119130

120131
// We have a class name, let's concatenate and store it!
121-
if ($class != '') {
122-
$namespace = trim($namespace);
123-
$fqClassName = $namespace . trim($class);
132+
if ($class !== '') {
133+
$fqClassName = trim(join('', $namespaceParts)) . trim($class);
124134
$classes[] = $fqClassName;
125135
$class = '';
126136
}
@@ -139,15 +149,15 @@ private function isBracedNamespace($index)
139149
$len = count($this->tokens);
140150
while ($index++ < $len) {
141151
if (!is_array($this->tokens[$index])) {
142-
if ($this->tokens[$index] == ';') {
152+
if ($this->tokens[$index] === ';') {
143153
return false;
144-
} else if ($this->tokens[$index] == '{') {
154+
} else if ($this->tokens[$index] === '{') {
145155
return true;
146156
}
147157
continue;
148158
}
149159

150-
if (!in_array($this->tokens[$index][0], [T_WHITESPACE, T_STRING, T_NS_SEPARATOR])) {
160+
if (!isset(self::NAMESPACE_TOKENS[$this->tokens[$index][0]])) {
151161
throw new InvalidFileException('Namespace not defined properly');
152162
}
153163
}

setup/src/Magento/Setup/Module/Di/Code/Scanner/PhpScanner.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,19 +170,16 @@ protected function _fetchMissingExtensionAttributesClasses($reflectionClass, $fi
170170
*/
171171
public function collectEntities(array $files)
172172
{
173-
$output = [];
173+
$output = [[]];
174174
foreach ($files as $file) {
175175
$classes = $this->_getDeclaredClasses($file);
176176
foreach ($classes as $className) {
177177
$reflectionClass = new \ReflectionClass($className);
178-
$output = array_merge(
179-
$output,
180-
$this->_fetchFactories($reflectionClass, $file),
181-
$this->_fetchMissingExtensionAttributesClasses($reflectionClass, $file)
182-
);
178+
$output [] = $this->_fetchFactories($reflectionClass, $file);
179+
$output [] = $this->_fetchMissingExtensionAttributesClasses($reflectionClass, $file);
183180
}
184181
}
185-
return array_unique($output);
182+
return array_unique(array_merge(...$output));
186183
}
187184

188185
/**

setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/BackslashTrim.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010

1111
class BackslashTrim implements ModificationInterface
1212
{
13+
/**
14+
* Argument keys which require recursive resolving
15+
*/
16+
private const RECURSIVE_ARGUMENT_KEYS = [
17+
'_i_' => true, // shared instance of a class or interface
18+
'_ins_' => true // non-shared instance of a class or interface
19+
];
20+
1321
/**
1422
* Modifies input config
1523
*
@@ -48,7 +56,6 @@ private function resolveInstancesNames(array $arguments)
4856
* Resolves instances arguments
4957
*
5058
* @param array $argument
51-
* @return array
5259
*/
5360
private function resolveArguments(&$argument)
5461
{
@@ -57,14 +64,12 @@ private function resolveArguments(&$argument)
5764
}
5865

5966
foreach ($argument as $key => &$value) {
60-
if (in_array($key, ['_i_', '_ins_'], true)) {
67+
if (isset(self::RECURSIVE_ARGUMENT_KEYS[$key])) {
6168
$value = ltrim($value, '\\');
6269
continue;
6370
}
6471

65-
if (is_array($value)) {
66-
$this->resolveArguments($value);
67-
}
72+
$this->resolveArguments($value);
6873
}
6974
return;
7075
}

setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/PreferencesResolving.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010

1111
class PreferencesResolving implements ModificationInterface
1212
{
13+
/**
14+
* Argument keys which require recursive resolving
15+
*/
16+
private const RECURSIVE_ARGUMENT_KEYS = [
17+
'_i_' => true, // shared instance of a class or interface
18+
'_ins_' => true // non-shared instance of a class or interface
19+
];
20+
1321
/**
1422
* Modifies input config
1523
*
@@ -32,7 +40,6 @@ public function modify(array $config)
3240
*
3341
* @param array $argument
3442
* @param array $preferences
35-
* @return array
3643
*/
3744
private function resolvePreferences(&$argument, &$preferences)
3845
{
@@ -41,14 +48,12 @@ private function resolvePreferences(&$argument, &$preferences)
4148
}
4249

4350
foreach ($argument as $key => &$value) {
44-
if (in_array($key, ['_i_', '_ins_'], true)) {
51+
if (isset(self::RECURSIVE_ARGUMENT_KEYS[$key])) {
4552
$value = $this->resolvePreferenceRecursive($value, $preferences);
4653
continue;
4754
}
4855

49-
if (is_array($value)) {
50-
$this->resolvePreferences($value, $preferences);
51-
}
56+
$this->resolvePreferences($value, $preferences);
5257
}
5358
}
5459

setup/src/Magento/Setup/Module/Di/Compiler/Config/Reader.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public function generateCachePerScope(
8484
}
8585

8686
$config = [];
87-
87+
8888
$this->fillThirdPartyInterfaces($areaConfig, $definitionsCollection);
8989
$config['arguments'] = $this->getConfigForScope($definitionsCollection, $areaConfig);
9090

@@ -113,11 +113,10 @@ private function getConfigForScope(DefinitionsCollection $definitionsCollection,
113113
{
114114
$constructors = [];
115115
$argumentsResolver = $this->argumentsResolverFactory->create($config);
116-
foreach ($definitionsCollection->getInstancesNamesList() as $instanceType) {
116+
foreach ($definitionsCollection->getCollection() as $instanceType => $constructor) {
117117
if (!$this->typeReader->isConcrete($instanceType)) {
118118
continue;
119119
}
120-
$constructor = $definitionsCollection->getInstanceArguments($instanceType);
121120
$constructors[$instanceType] = $argumentsResolver->getResolvedConstructorArguments(
122121
$instanceType,
123122
$constructor
@@ -151,14 +150,9 @@ private function getConfigForScope(DefinitionsCollection $definitionsCollection,
151150
*/
152151
private function fillThirdPartyInterfaces(ConfigInterface $config, DefinitionsCollection $definitionsCollection)
153152
{
154-
$definedInstances = $definitionsCollection->getInstancesNamesList();
155-
156-
foreach (array_keys($config->getPreferences()) as $interface) {
157-
if (in_array($interface, $definedInstances)) {
158-
continue;
159-
}
160-
161-
$definitionsCollection->addDefinition($interface, []);
162-
}
153+
$definedInstances = $definitionsCollection->getCollection();
154+
$newInstances = array_fill_keys(array_keys($config->getPreferences()), []);
155+
$newCollection = array_merge($newInstances, $definedInstances);
156+
$definitionsCollection->initialize($newCollection);
163157
}
164158
}

0 commit comments

Comments
 (0)