我有为路由组件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 limitbacktrack 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

09-25 18:08
查看更多