Что является более эффективным, строковые функции PHP или регулярное выражение в PHP? - PullRequest
18 голосов
/ 11 марта 2009

Я пишу код PHP для анализа строки. Это должно быть как можно быстрее, поэтому стоит ли использовать регулярные выражения? Я догадываюсь, что строковые функции PHP дороже, но это только предположение. Что правда?

Вот что конкретно мне нужно сделать со строкой:

Возьмите первую половину (основываясь на третьем расположении подстроки "000000") и сравните ее хеш со следующими 20 байтами, отбрасывая все, что осталось.

Разобрать 9-й байт до следующего "000000" как один фрагмент данных. Затем возьмите следующие 19 байтов после этого и разделите их на 8 (бросьте 1) и 8. Затем я сделаю некоторые другие вещи, которые преобразуют эти две 8-байтовые строки в даты.

Так вот что мне нужно сделать.

Ответы [ 9 ]

16 голосов
/ 11 марта 2009

Это зависит от вашего случая: если вы пытаетесь сделать что-то довольно простое (например: найти строку, заменить подстроку чем-то другим), то обычные строковые функции - это путь. Если вы хотите сделать что-то более сложное (например, поиск IP-адресов), то функции Regex, безусловно, являются лучшим выбором.

У меня нет профилированных регулярных выражений, поэтому я не могу сказать, что они будут быстрее во время выполнения, но я могу вам сказать, что дополнительное время, потраченное на то, чтобы собрать вместе эквивалент с использованием основных функций, не стоило бы *. 1003 *


Изменить с новой информацией в ОП:

Звучит так, как будто вам действительно нужно выполнить ряд небольших строковых операций здесь. Поскольку каждый из них является довольно простым, и я сомневаюсь, что вы сможете выполнить все эти шаги (или даже пару этих шагов) одновременно, используя регулярное выражение, я бы пошел с основными функциями:

Возьмите первую половину (основываясь на третьем расположении подстроки "000000") и сравните ее хеш со следующими 20 байтами, отбрасывая все, что осталось.

Использование: strpos() и substr()
Или: /$(.*?0{6}.*?0{6}.*?)0{6}/

Затем возьмите следующие 19 байтов после этого и разделите их на 8 (бросок 1) и 8.

Использование: substr() - (я полагаю, здесь вы имеете в виду 17 байтов - 8 + 1 + 8)

$part1 = substr($myStr, $currPos, 8);
$part2 = substr($myStr, $currPos + 9, 8);
6 голосов
/ 11 марта 2009

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

РЕДАКТИРОВАТЬ: Для этой конкретной проблемы, которую вы опубликовали, я бы предпочел строковые операции, но только потому, что я не знал бы, как это сделать в регулярных выражениях. Это кажется довольно простым, за исключением хэша, поэтому я думаю, что регулярные выражения / строковые функции не будут иметь большого значения.

6 голосов
/ 11 марта 2009

Я полагаю, что существует порог, с которого регулярное выражение работает быстрее, чем набор вызовов строковых функций PHP. Во всяком случае, многое зависит от того, что вы делаете. Вы должны выяснить баланс.

Теперь, когда вы отредактировали свой вопрос. Я бы использовал строковые функции для того, что вы пытаетесь достичь. strpos () и substr () - это то, что приходит на ум с первого взгляда.

4 голосов
/ 12 марта 2009

В общем случае строковые функции работают быстрее, а функции регулярных выражений более гибкие.

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

4 голосов
/ 11 марта 2009

Если то, что вы делаете, разумно делать с помощью строковых функций, вам следует использовать их. Например, если вы определяете, встречается ли постоянная строка 'abc' в $value, вы определенно хотите проверить strpos($value, 'abc') !== false, а не preg_match('/abc/', $value). Если вы обнаружите, что выполняете много перестановок строк и преобразований, чтобы выполнить то, что вы сделали бы с помощью регулярных выражений, вы почти наверняка столкнетесь с потерей как производительности, так и удобства обслуживания.

Однако, когда дело касается скорости, когда дело доходит до нее, не думай об этом, следи за ней. Команда time - ваш друг.

2 голосов
/ 20 апреля 2017

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

StrPos ()

$ time php -r '$i = 0; while($i++ < 1000000) strpos("abc", "a");'

real    0m0.380s
user    0m0.368s
sys    0m0.008s

preg_match ()

$ time php -r '$i = 0; while($i++ < 1000000) preg_match("/abc/", "a");'

real    0m0.441s
user    0m0.432s
sys    0m0.004s
1 голос
/ 11 марта 2009

Родные строковые функции работают намного быстрее. Преимущество регулярного выражения в том, что вы можете делать с ними практически все.

0 голосов
/ 14 сентября 2018

Я искал некоторую информацию о производительности регулярных выражений - поскольку мне нужно много раз искать - и правда в том, что зависит от того, чего вы хотите достичь . Для своих целей я протестировал один тип поиска для сравнения производительности.

Спецификация: Мне нужно найти простую строку в массиве строк. Для тестирования у меня есть $testArray, который представляет собой массив из ~ 11k многословных фраз, собранных из статьи о Толкине (например, строки «История повелителя колец», «Кристофер Толкиен»). Поскольку я хочу найти только фразы, содержащие точное слово, я не могу использовать функцию strpos(), например. при поиске «ring» он также находит фразы со словом «ringtone».

Код с использованием функций php:

$results = array();
$searchWord = 'rings';
foreach ($testArray as $phrase){
  $phraseArr = explode(' ', $phrase);
  if(in_array($searchWord, $phraseArr)){
    $results[] = $phrase;
  }
}

Код с использованием функции регулярного выражения:

$results = array();
$pattern= "/( |^)rings( |$)/";
$results = preg_grep($pattern, $testArray);

Я обнаружил, что в этом случае функция регулярного выражения была примерно в 10 раз быстрее

Время выполнения для 100 поисковых запросов было (с использованием различных слов)

  • от 0,3436 до 0,3468 секунды для функций php
  • от 0,0332 до 0,0406 секунды для регулярных выражений

Такой поиск может быть тривиальным, но для более сложных задач я предполагаю, что было бы чрезвычайно трудно / невозможно реализовать его без регулярных выражений только для нативных функций php.

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

Edit:

Я просто понимаю, что эта тема о "функциях PHP string ", и мой тестовый код использует функции explode() и in_array(). Поэтому я попробовал другой подход. Поскольку мой разделитель - пробел, метод поиска ниже также работает и использует функцию strpos().

Код с использованием функции strpos():

$results = array();
$searchWord = 'rings';
foreach ($testArray as $phrase){
  if(strpos(' ' . $phrase . ' ', ' ' . $searchWord . ' ')!==FALSE){
    $results[] = $phrase;
  }
} 

Но все же результаты были намного хуже, чем в случае с регулярными выражениями.

Итак сводка производительности это:

  • от 0,3436 до 0,3468 секунды для функций массива php
  • от 0.2001 до 0,2273 секунды для strpos() функции
  • от 0,0332 до 0,0406 секунды для регулярного выражения

Все еще регулярное выражение - большой победитель.

0 голосов
/ 11 марта 2009

Зависит от ваших потребностей. Большинство операций с регулярными выражениями выполняются быстрее, чем можно было бы подумать, и даже могут превзойти встроенные строковые функции в определенных тривиальных операциях. Обратите внимание, что я имею в виду библиотеку preg, а не встроенную библиотеку регулярных выражений, которая работает довольно медленно.

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