我有为路由组件here is the full code编写的这段代码,它基本上从许多小(特定于路由的)中构建出一批大数量的正则表达式(取决于配置值),以验证给定的请求是否可以或无法通过已注册的路线进行映射。
一般过程涉及首先装饰每条路线,以便使用占位符的路线,例如
/path/to/:variable_name
变成一个正则表达式,例如:
/path/to/(?P<R1V1>[^/]+)
并且在验证时,每条任意大小的批处理都将这些路由粘合到单个正则表达式中。
对于“正常”用法,例如500 strip 有1-4个占位符的路由,它工作得很好。但是在对它进行基准测试时,我注意到对于大量的占位符和以及大量的路由(当前有11个占位符和50000条路由),我所拥有的代码未能找到最后一条注册的路由。
我无法弄清楚的原因。据我所知,该事物的行为应大致相同,每个数量级取(可能是O表示生锈)O(n * m)次(n为批数量,m为多少)正则表达式有一批)。
也许这是我正在测试的方式吗?如果不是,您能指出我正在做的任何有问题的事情吗?
如果有什么用,我使用的基准就是这里的基准
<?php
require dirname(__FILE__).'/../vendor/autoload.php';
$router = new \CFV\Router();
$dispatcher = new \CFV\Dispatcher();
$dispatcher::$ROUTES_PER_LOT = 20;
// $dispatcher::$THROW_ON_FAIL = true;
$callback = function (){};
$num_args = 11;
$routes_amount = 50000;
$matches_amount = 1;
$args = implode('/', array_map(function($i){ return ':arg' . $i; }, range(1, $num_args)));
$params = implode('/', array_map(function($i){ return '_arg' . $i; }, range(1, $num_args)));
$last_tried = '';
$load_start = microtime(true);
for ($i = 0, $str = 'a'; $i < $routes_amount; $i++, $str++) {
$router->connect("/$str/$args", $callback);
$last_tried = "/$str/$params";
}
printf("Took: %fs to load all\n", microtime(true) - $load_start);
$dispatcher->setRouter($router);
$search_start = microtime(true);
$found = $dispatcher->dispatch($last_tried);
printf("Took: %fs searching all\n", microtime(true) - $search_start);
任何指针都将非常棒。
最佳答案
有一些限制。从the manual:
另外,还有PCRE的recursion limit和backtrack limit
引用:
http://php.net/manual/en/regexp.reference.recursive.php
http://php.net/pcre.configuration#ini.pcre.recursion-limit
http://php.net/pcre.configuration#ini.pcre.backtrack-limit