Permalink
Browse files

bug #30058 [Routing] fix perf issue when dumping large number of rout…

…es (nicolas-grekas)

This PR was merged into the 4.2 branch.

Discussion
----------

[Routing] fix perf issue when dumping large number of routes

| Q             | A
| ------------- | ---
| Branch?       | 4.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #29918
| License       | MIT
| Doc PR        | -

In my reproducer, dumping 12k routes goes from 40s to 3s without xdebug, and from 50s to 12s with xdebug.

There is a lower level issue which is that `strpos` is called 16M times, but that's still a lot faster than calling `preg_match` 16M times. Reducing the number of checks is certainly possible, but that would be more involving. This could happen on master if someone is up to dig into it.

Commits
-------

872efe5 [Routing] fix perf issue when dumping large number of routes
  • Loading branch information...
nicolas-grekas committed Feb 7, 2019
2 parents 0bb0c7f + 872efe5 commit fd720ed704ae3a2be745198c9a7630fe98fca995
Showing with 5 additions and 4 deletions.
  1. +5 −4 src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -159,6 +159,7 @@ private function groupStaticRoutes(RouteCollection $collection): array
foreach ($collection->all() as $name => $route) {
$compiledRoute = $route->compile();
$staticPrefix = rtrim($compiledRoute->getStaticPrefix(), '/');
$hostRegex = $compiledRoute->getHostRegex();
$regex = $compiledRoute->getRegex();
if ($hasTrailingSlash = '/' !== $route->getPath()) {
@@ -173,17 +174,17 @@ private function groupStaticRoutes(RouteCollection $collection): array
if ($hasTrailingSlash) {
$url = substr($url, 0, -1);
}
foreach ($dynamicRegex as list($hostRx, $rx)) {
if (preg_match($rx, $url) && (!$host || !$hostRx || preg_match($hostRx, $host))) {
$dynamicRegex[] = [$hostRegex, $regex];
foreach ($dynamicRegex as list($hostRx, $rx, $prefix)) {
if (('' === $prefix || 0 === strpos($url, $prefix)) && preg_match($rx, $url) && (!$host || !$hostRx || preg_match($hostRx, $host))) {
$dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];
$dynamicRoutes->add($name, $route);
continue 2;
}
}
$staticRoutes[$url][$name] = [$route, $hasTrailingSlash];
} else {
$dynamicRegex[] = [$hostRegex, $regex];
$dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];
$dynamicRoutes->add($name, $route);
}
}

0 comments on commit fd720ed

Please sign in to comment.