Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在preg_replace()之前使用strpos()是否更快?_Php_Regex_Preg Replace_Strpos - Fatal编程技术网

Php 在preg_replace()之前使用strpos()是否更快?

Php 在preg_replace()之前使用strpos()是否更快?,php,regex,preg-replace,strpos,Php,Regex,Preg Replace,Strpos,假设我们在数百万个post字符串上使用preg_替换: function makeClickableLinks($s) { return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s); } 假设所有帖子中只有10%包含链接,那么检查strpos$stri

假设我们在数百万个post字符串上使用preg_替换:

function makeClickableLinks($s) {
    return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s);
}

假设所有帖子中只有10%包含链接,那么检查strpos$string,'http'!=调用preg_replace之前为false?若然,原因为何?preg_replace不是在内部执行一些预测试吗?

是的,使用简单的搜索(如strpos)比编译和执行正则表达式快得多,而替换本身必须进行内存复制。如果你在做成百上千的搜索,那就没有意义了,但是如果你在做成百上千万的搜索,尤其是其中只有10%包含http,那么首先做一个简单的搜索是值得的


最终,100%确定的唯一方法是对其进行基准测试,但我可以相当肯定的是,您将首先使用strpos获得一些改进。

是的,使用类似strpos的简单搜索比编译和执行正则表达式快得多,而替换本身必须进行内存复制。如果你在做成百上千的搜索,那就没有意义了,但是如果你在做成百上千万的搜索,尤其是其中只有10%包含http,那么首先做一个简单的搜索是值得的

最终,100%确定的唯一方法是对其进行基准测试,但我可以相当肯定的是,您将首先使用strpos获得一些改进。

令人惊讶的是,是的

以下是供您使用这两个函数分析10000000个字符串的基准:

测试1-与模式匹配的字符串:

仅preg_更换就花费了10.9626309872秒 preg_replace前的STRPO耗时12.6124269962秒← 慢的

测试2-与模式不匹配的字符串:

仅preg_更换就花费了6.51636195183秒 preg_更换前的STRPO耗时2.9120569291秒← 更快

测试3-10%的字符串与模式匹配:

仅preg_更换就花费了7.43295097351秒 preg_更换前的STRPO耗时4.31978201866秒← 更快

它只是两个字符串上的一个简单基准,但速度上有明显的差异

以下是10%情况下的测试线束:

<?php
$string1 = "Here is a great new site to visit at http://example.com so go there now!";
$string2 = "Here is a great new site to visit at ftp://example.com so go there now!";

function makeClickableLinks1($s) {
    return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s);
}

function makeClickableLinks2($s) {
    return strpos($s, 'http') !== false ? preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s) : null;
}

/* Begin test harness */

$loops = 10000000;

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

/* Test using only preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks1($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "preg_replace alone took $time seconds<br/>";

/* Test using strpos before preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks2($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "strpos before preg_replace took $time seconds<br/>";
?>
令人惊讶的是,是的

以下是供您使用这两个函数分析10000000个字符串的基准:

测试1-与模式匹配的字符串:

仅preg_更换就花费了10.9626309872秒 preg_replace前的STRPO耗时12.6124269962秒← 慢的

测试2-与模式不匹配的字符串:

仅preg_更换就花费了6.51636195183秒 preg_更换前的STRPO耗时2.9120569291秒← 更快

测试3-10%的字符串与模式匹配:

仅preg_更换就花费了7.43295097351秒 preg_更换前的STRPO耗时4.31978201866秒← 更快

它只是两个字符串上的一个简单基准,但速度上有明显的差异

以下是10%情况下的测试线束:

<?php
$string1 = "Here is a great new site to visit at http://example.com so go there now!";
$string2 = "Here is a great new site to visit at ftp://example.com so go there now!";

function makeClickableLinks1($s) {
    return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s);
}

function makeClickableLinks2($s) {
    return strpos($s, 'http') !== false ? preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s) : null;
}

/* Begin test harness */

$loops = 10000000;

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

/* Test using only preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks1($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "preg_replace alone took $time seconds<br/>";

/* Test using strpos before preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks2($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "strpos before preg_replace took $time seconds<br/>";
?>

我敢肯定这听起来不是很有说服力,这听起来好像你不确定你在说什么!如果你愿意,那么你可以证明这一点!你的答案的证据在哪里?我的想法是,如果有人问优化问题,他们的工作就是做基准测试。你真的认为优化qs的所有答案都应该有证据支持吗?我认为这是一个不切实际的期望。这并不完全是关于基准测试2。他们的工作是进行基准测试,然后他们会问什么?假设一下?!3.你真的认为优化qs的所有答案都应该有证据支持吗?对如果可能的话,每个答案都应该有一个证明,因为这样读者可以更容易地理解它,并直接看到它是如何工作的!你能给我一些优化答案的例子,其中包括“证明”一个没有标杆的强有力的词吗?优化是如此依赖数据,我只是看不到它…仅供参考,PCRE将首先搜索字符串中是否有https,我认为这种模式甚至不需要这样做,因为它从固定文本开始。这就是为什么我认为使用strpos是多余的,并且会降低处理速度。但只有一个基准可以确定,毕竟我不知道PHP自己做什么,所以你不应该在回答中断言这样的东西,除非你先检查它们。我可以相当肯定这听起来不是很有说服力,这听起来你不确定你在这里说的是什么!如果你愿意,那么你可以证明这一点!你的答案的证据在哪里?我的想法是,如果有人问优化问题,他们的工作就是做基准测试。你真的认为优化qs的所有答案都应该有证据支持吗?我认为这是一个不切实际的期望。这并不完全是关于基准测试2。他们的工作是进行基准测试,然后他们会问什么?假设一下?!3.你真的认为优化qs的所有答案都应该有证据支持吗?对如果可能的话,每个答案都应该有答案

一个证明,因为这样读者可以更容易地理解它,并直接看到它是如何工作的!你能给我一些优化答案的例子,其中包括“证明”一个没有标杆的强有力的词吗?优化是如此依赖数据,我只是看不到它…仅供参考,PCRE将首先搜索字符串中是否有https,我认为这种模式甚至不需要这样做,因为它从固定文本开始。这就是为什么我认为使用strpos是多余的,并且会降低处理速度。但只有基准测试才能确定,毕竟我不知道PHP自己做什么,所以除非先检查它们,否则不应该在答案中断言这样的东西。令人惊讶的是,是的!这是一个好问题。我不认为基准测试是一个意见问题->投票重新开始。令人惊讶的是,是的!这是一个好问题。我不认为标杆管理是一个意见问题->投票重新开始。谢谢。如果strpos$i%10,一个次要的优化可能是完全避免函数调用$string2:$string1,'http'!==false makeClickableLinks1$i%10$string2:$string1;。嗨,顺便问一下,问得好。您无法提前知道字符串是否具有http。因此,唯一的方法是在函数中始终使用strpo,或者永远不要使用它。这两种情况正是正在测试的情况,为了清楚起见,还有第三种情况,但是必须始终调用一些makeClickableLinks函数才能进行有效的测试。希望这能有所帮助。对我来说,这是一个非常重要的答案,因为我有多个preg_-replace,有些带有回调,可以在论坛帖子中自动生成链接、列表、bbcodes等,我知道它们中的大多数永远不会匹配正则表达式。makeClickableLinks正则表达式应该是所有正则表达式中最快的,也许一个非常简单的正则表达式是如此之快,以至于根本不需要strpos?!因此,答案是我将在所有情况下使用strpo。你认为用preg_replace_回调和测试是值得的吗。。。有趣的链接。我不知道如何应用这个“技巧”,因为您希望匹配所有http://事件,而不排除任何一个。但是,我使用回调版本再次运行了测试,而strpos版本大约快2.2倍。我没有太多的时间来探索这个问题,但这里有一个你可以尝试的粘贴:。我希望这个答案能重新打开。你只需要再投3票就可以了。祝你好运!依赖回调技巧要慢10倍。这里是:函数makeClickableLinks3$s{return preg\u replace\u callback'@^?:?!http.*$|?:https?:/[-\w\.]+[-\w]+:\d+/[\w/\.-]*\\s+.[^\.\s]@,函数$m{return m!$m[1]?$m[0]:,$s;}。这样,我肯定会使用strpos;非常感谢。如果strpos$i%10,一个次要的优化可能是完全避免函数调用$string2:$string1,'http'!==false makeClickableLinks1$i%10$string2:$string1;。嗨,顺便问一下,问得好。您无法提前知道字符串是否具有http。因此,唯一的方法是在函数中始终使用strpo,或者永远不要使用它。这两种情况正是正在测试的情况,为了清楚起见,还有第三种情况,但是必须始终调用一些makeClickableLinks函数才能进行有效的测试。希望这能有所帮助。对我来说,这是一个非常重要的答案,因为我有多个preg_-replace,有些带有回调,可以在论坛帖子中自动生成链接、列表、bbcodes等,我知道它们中的大多数永远不会匹配正则表达式。makeClickableLinks正则表达式应该是所有正则表达式中最快的,也许一个非常简单的正则表达式是如此之快,以至于根本不需要strpos?!因此,答案是我将在所有情况下使用strpo。你认为用preg_replace_回调和测试是值得的吗。。。有趣的链接。我不知道如何应用这个“技巧”,因为您希望匹配所有http://事件,而不排除任何一个。但是,我使用回调版本再次运行了测试,而strpos版本大约快2.2倍。我没有太多的时间来探索这个问题,但这里有一个你可以尝试的粘贴:。我希望这个答案能重新打开。你只需要再投3票就可以了。祝你好运!依赖回调技巧要慢10倍。这里是:函数makeClickableLinks3$s{return preg\u replace\u callback'@^?:?!http.*$|?:https?:/[-\w\.]+[-\w]+:\d+/[\w/\.-]*\\s+.[^\.\s]@,函数$m{return m!$m[1]?$m[0]:,$s;}。这样,我肯定会使用strpos;
"Here is a great new site to visit at ftp://example.com so go there now!" (90%)
"Here is a great new site to visit at http://example.com so go there now!" (10%)
<?php
$string1 = "Here is a great new site to visit at http://example.com so go there now!";
$string2 = "Here is a great new site to visit at ftp://example.com so go there now!";

function makeClickableLinks1($s) {
    return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s);
}

function makeClickableLinks2($s) {
    return strpos($s, 'http') !== false ? preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s) : null;
}

/* Begin test harness */

$loops = 10000000;

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

/* Test using only preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks1($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "preg_replace alone took $time seconds<br/>";

/* Test using strpos before preg_replace */

$time_start = microtime_float();
for($i = 0; $i < $loops; $i++) {
    // Only 10% of strings will have "http"
    makeClickableLinks2($i % 10 ? $string2 : $string1);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "strpos before preg_replace took $time seconds<br/>";
?>