оптимизация скорости preg_replace - PullRequest
2 голосов
/ 22 января 2010

Если посмотреть на принятый ответ , удалив все символы из строки, оставив цифры , автор добавил + после выражения

$str = preg_replace('/[^0-9.]+/', '', $str);

чтобы найти подстроки, а не отдельные вхождения, чтобы удалить. Для функциональности + не является обязательным. Но я начал задаваться вопросом, является ли добавление + быстрее или нет. (Или нет никакой разницы?)

Я бы предположил, что это быстрее из-за меньшей обработки строк и памяти. Но я также мог понять, что более сложные выражения регулярных выражений медленнее, чем простые.

Таким образом, при использовании этого метода для удаления подстрок следует пытаться найти большие или маленькие подстроки?

Ответы [ 3 ]

1 голос
/ 22 января 2010

Не читайте слишком много в результатах тестов. Их невероятно сложно сделать хорошо. На самом деле, единственное, что вы должны извлечь из этого, это то, что повторение может быть более быстрым для определенных типов строк, где диапазон повторения велик.

Этот тип материала может легко меняться в другой версии PCRE.


function tst($pat, $str) {
    $start = microtime(true);
    preg_replace($pat, '', $str);
    return microtime(true) - $start;
}
$strs = array(
    'letters' => str_repeat("a", 20000),
    'numbers' => str_repeat("1", 20000),
    'mostly_letters' => str_repeat("aaaaaaaaaaaaa5", 20000),
    'mostly_numbers' => str_repeat("5555555555555a", 20000)
);
$pats = array(
    'rep' => '/[^0-9.]+/',
    'norep' => '/[^0-9.]/'
);

//precompile patterns(php caches them per script) and warm up microtime
microtime(true);
preg_replace($pats['rep'], '', 'foo');
preg_replace($pats['norep'], '', 'foo');

foreach ($strs as $strname => $str) {
    echo "$strname\n";
    foreach ($pats as $patname => $pat) {
        printf("%10s    %.5f\n", $patname, tst($pat, $str));
    }
}

1 голос
/ 25 января 2010

Я провел несколько тестов скорости, как предложено Крис . По сравнению с его кодом я:

  • добавлен str_replace для сравнения:
$str_replace_array = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.');

function tst($pat, $str) {
    global $str_replace_array;
    $start = microtime(true);
    if($pat == '')
        str_replace($str_replace_array, '', $str);
    else
        preg_replace($pat, '', $str);
    return microtime(true) - $start;
}
  • сделал все строки одинаковой длины, чтобы результаты можно было сравнить лучше

Результаты в:

letters
         rep    0.00298
       norep    0.06953
 str_replace    0.00406

numbers
         rep    0.02867
       norep    0.02612
 str_replace    0.01242

mostly_letters
         rep    0.00931
       norep    0.06649
 str_replace    0.00593

mostly_numbers
         rep    0.03285
       norep    0.02942
 str_replace    0.01359

Это показывает, что повторяющееся регулярное выражение (с добавленным +) намного быстрее при замене больших блоков (меньше обработки памяти?), Но никакое повторяющееся регулярное выражение не является немного более быстрым, когда не требуется много замены.

Кроме того, str_replace в основном всегда на быстрее (в два раза быстрее), чем замена регулярного выражения, за исключением случаев, когда регулярное выражение соответствует всей строке.

0 голосов
/ 22 января 2010

Я не проводил никакого теста, но с + вы соответствовали большему количеству символов, поэтому процесс замены должен выполняться меньше раз. Если вы не пишете + в регулярном выражении, замена выполняется для каждого символа вместо замены всей подстроки, поэтому я думаю, что это медленнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...