8000 bug #20374 [FrameworkBundle] Improve performance of ControllerNamePar… · src-run/symfony@e62b602 · GitHub
[go: up one dir, main page]

Skip to content

Commit e62b602

Browse files
bug symfony#20374 [FrameworkBundle] Improve performance of ControllerNameParser (enumag)
This PR was merged into the 2.7 branch. Discussion ---------- [FrameworkBundle] Improve performance of ControllerNameParser | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | Today I was searching for bottlenecks in my application using Blackfire. And among other things I found one in Symfony. Blackfire showed that `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser::findAlternative()` was called almost 300 times which took 28 miliseconds. It turns out that `Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader::load()` is calling `ControllerNameParser::parse()` without actually needing to do so because `$controller` is in the class::method notation already. `ControllerNameParser` threw an exception, DelegatingLoader caught and ignored it - that's ok. The problem is that generating the exception message took a lot of time because findAlternative is slow. In my case it called the levenshtein function over 5000 times which was completely useless because the exception is ignored anyway. Commits ------- cf333f3 [FrameworkBundle] Improve performance of ControllerNameParser
2 parents 8c2a77b + cf333f3 commit e62b602

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ public function __construct(KernelInterface $kernel)
4646
*/
4747
public function parse($controller)
4848
{
49-
$originalController = $controller;
50-
if (3 !== count($parts = explode(':', $controller))) {
49+
$parts = explode(':', $controller);
50+
if (3 !== count($parts) || in_array('', $parts, true)) {
5151
throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller));
5252
}
5353

54+
$originalController = $controller;
5455
list($bundle, $controller, $action) = $parts;
5556
$controller = str_replace('/', '\\', $controller);
5657
$bundles = array();

src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* DelegatingLoader delegates route loading to other loaders using a loader resolver.
2222
*
2323
* This implementation resolves the _controller attribute from the short notation
24-
* to the fully-qualified form (from a:b:c to class:method).
24+
* to the fully-qualified form (from a:b:c to class::method).
2525
*
2626
* @author Fabien Potencier <fabien@symfony.com>
2727
*/
@@ -85,15 +85,17 @@ public function load($resource, $type = null)
8585
$this->loading = false;
8686

8787
foreach ($collection->all() as $route) {
88-
if ($controller = $route->getDefault('_controller')) {
89-
try {
90-
$controller = $this->parser->parse($controller);
91-
} catch (\InvalidArgumentException $e) {
92-
// unable to optimize unknown notation
93-
}
88+
if (!$controller = $route->getDefault('_controller')) {
89+
continue;
90+
}
9491

95-
$route->setDefault('_controller', $controller);
92+
try {
93+
$controller = $this->parser->parse($controller);
94+
} catch (\InvalidArgumentException $e) {
95+
// unable to optimize unknown notation
9696
}
97+
98+
$route->setDefault('_controller', $controller);
9799
}
98100

99101
return $collection;

0 commit comments

Comments
 (0)
0