Skip to content

Commit 4ef0b3e

Browse files
committed
feature symfony#26059 [Routing] Match 77.7x faster by compiling routes in one regexp (nicolas-grekas)
This PR was merged into the 4.1-dev branch. Discussion ---------- [Routing] Match 77.7x faster by compiling routes in one regexp | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Builds on top of symfony#25961 and http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html to make routing 77.7x faster (measured when matching the last dynamic route of 400 static + 400 dynamic routes.) More benchs welcomed. - [x] check static routes first in a switch - [x] group same-modifiers regexps - [x] put condition-less routes in a static map, in a switch's "default" - [x] match host+pathinfo at the same time - [x] group same-host regexps in sub-patterns - [x] consider the host to move more static routes in the static switch - [x] move static single-route "case" to "default" by adding requirements to $routes - [x] group same-static-prefix in sub-patterns - [x] group consecutive same-regex in a single "case" - [x] move dynamic single-route "case" to "default" by adding requirements to $routes - [x] extract host variables from the main match and remove the current 2nd match - [x] extend same-prefix grouping to placeholders - [x] group same-suffix hosts together Here is my benchmarking code: ```php <?php namespace Symfony\Component\Routing; require 'vendor/autoload.php'; $routes = new RouteCollection(); for ($i = 0; $i < 400; ++$i) { $routes->add('r'.$i, new Route('/abc'.$i)); $routes->add('f'.$i, new Route('/abc{foo}/'.$i)); } $dumper = new Matcher\Dumper\PhpMatcherDumper($routes); eval('?'.'>'.$dumper->dump()); $router = new \ProjectUrlMatcher(new RequestContext()); $i = 10000; $s = microtime(1); while (--$i) { $router->match('/abcdef/399'); } echo 'Symfony: ', 1000 * (microtime(1) - $s), "\n"; namespace FastRoute; $dispatcher = simpleDispatcher(function(RouteCollector $r) { for ($i = 0; $i < 400; ++$i) { $r->addRoute('GET', '/abc'.$i, 'r'.$i); $r->addRoute('GET', '/abc{foo}/'.$i, 'f'.$i); } }); $i = 10000; $s = microtime(1); while (--$i) { $dispatcher->dispatch('GET', '/abcdef/399'); } echo 'FastRoute: ', 1000 * (microtime(1) - $s), "\n"; ``` Commits ------- f933f70 [Routing] Match 77.7x faster by compiling routes in one regexp
2 parents 882ffe9 + f933f70 commit 4ef0b3e

20 files changed

+1511
-1754
lines changed

src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Routing\Generator\Dumper;
1313

14+
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
15+
1416
/**
1517
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
1618
*
@@ -88,7 +90,7 @@ private function generateDeclaredRoutes()
8890
$properties[] = $compiledRoute->getHostTokens();
8991
$properties[] = $route->getSchemes();
9092

91-
$routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
93+
$routes .= sprintf(" '%s' => %s,\n", $name, PhpMatcherDumper::export($properties));
9294
}
9395
$routes .= ' )';
9496

src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php

Lines changed: 0 additions & 159 deletions
This file was deleted.

src/Symfony/Component/Routing/Matcher/Dumper/DumperRoute.php

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)