Preg_replace Etkinliği

0 Cevap php

Executive Summary:

preg_replace() daha hızlı dize karşılaştırmaları daha koştu. Neden? Düzenli olmayan ifadeler yavaş olmalıdır?


Bir recent question verilen bir giriş içinde izin verilmeyen alt dizelerin bir dizi algılanması konusunda, ben, bir preg_replace() orijinal girişine dediğimiz sonucunu karşılaştırarak önerilen beri {[(1)] } girdi olarak desen bir dizi alabilir. Diğer çözümler, bir (veya birçok) döngüsü gerekli ise Dolayısıyla bu yöntem, benim tek bir if olabilir.

Gerçekten döngüler daha yaşatılabilir / az okunabilir, çünkü benim cevap münazara ilgilenmiyorum. Orada benim cevabım yine bir -1 tutan, ve ben bakım okunabilirliği / kolaylığı için kabul edeceğiz, ama büyük fay verimlilik eksikliği benim yöntemi ile dikkat çekti. Bu beni merak var ve bazı testler yapmak için götürdü. Benim sonuç bana biraz şaşırtıcı idi: tüm diğer faktörler eşit tutulan ile, preg_replace() herhangi bir diğer yöntem daha faster idi.

Can you explain why this was the case?

Bu testler için benim kod sonuçları ile birlikte aşağıda bulabilirsiniz:

$input = "In a recent question about detecting any of an array of disallowed substrings within a given input, I suggested comparing the result of a `preg_replace()` call to the original input, since `preg_replace()` can take an array of patterns as input. Thus my method for this could be a single `if` whereas the other solutions required one (or many) loops. I'm not interested in debating my answer, because really it is less readable/maintainable than the loops. However, the biggest fault pointed out with my method was a lack of efficiency. That got me curious, and led me to do some testing. My results were a bit surprising to me: with all other factors held equal, `preg_replace()` was **faster** than any of the other methods. Can you explain why this was the case?";
$input2 = "Short sentence - no matches";
$input3 = "Word";
$input4 = "Short sentence - matches loop";

$start1 = microtime(true);
$rejectedStrs = array("loop", "efficiency", "explain");
$p_matches = 0;
for ($i = 0; $i < 10000; $i++) {
    if (str_check($rejectedStrs, $input)) $p_matches++;
    if (str_check($rejectedStrs, $input2)) $p_matches++;
    if (str_check($rejectedStrs, $input3)) $p_matches++;
    if (str_check($rejectedStrs, $input4)) $p_matches++;
}

$start2 = microtime(true);
$rejectedStrs = array("loop", "efficiency", "explain");
$l_matches = 0;
for ($i = 0; $i < 10000; $i++) {
    if (loop_check($rejectedStrs, $input)) $l_matches++;
    if (loop_check($rejectedStrs, $input2)) $l_matches++;
    if (loop_check($rejectedStrs, $input3)) $l_matches++;
    if (loop_check($rejectedStrs, $input4)) $l_matches++;
}

$start3 = microtime(true);
$rejectedStrs = array("/loop/", "/efficiency/", "/explain/");
$s_matches = 0;
for ($i = 0; $i < 10000; $i++) {
    if (preg_check($rejectedStrs, $input)) $s_matches++;
    if (preg_check($rejectedStrs, $input2)) $s_matches++;
    if (preg_check($rejectedStrs, $input3)) $s_matches++;
    if (preg_check($rejectedStrs, $input4)) $s_matches++;
}

$end = microtime(true);
echo $p_matches." ".$l_matches." ".$s_matches."\n";
echo "str_match: ".$start1." ".$start2."= ".($start2-$start1)."\nloop_match: ".$start2." ".$start3."=".($start3-$start2)."\npreg_match: ".$start3." ".$end."=".($end-$start3);

function preg_check($rejectedStrs, $input) {
    if($input == preg_replace($rejectedStrs, "", $input)) 
        return true;
    return false;
}

function loop_check($badwords, $string) {

    foreach (str_word_count($string, 1) as $word) {
        foreach ($badwords as $bw) {
            if (stripos($word, $bw) === 0) {
                return false;
            }
        }
    }
    return true;
}

function str_check($badwords, $str) {
    foreach ($badwords as $word) {
        if (stripos(" $str ", " $word ") !== false) {
            return false;
        }
    }
    return true;
}

Results

20000 20000 20000

str_match: 1282270516.6934 1282270518.5881 = 1,894730091095

loop_match: 1282270518.5881 1282270523.0943 = 4,5061857700348

preg_match: 1282270523.0943 1282270523.6191 = ,52475500106812

0 Cevap