последовательный strpos () быстрее, чем функция с одним preg_match? - PullRequest
4 голосов
/ 19 января 2010

Мне нужно проверить, существует ли какая-либо из строк 'hello', 'i am', 'dumb' в более длинной строке с именем $ ohreally, , если хотя бы одна из них существует, мой тест закончен, и знание, что ни один из других не произойдет, если один из них имеет.

В этих условиях я прошу вашей помощи по наиболее эффективному способу написания этого поиска,

strpos () 3 раза, как это?

if (strpos ($ohreally, 'hello')){return false;}  
   else if (strpos ($ohreally, 'i am')){return false;}  
   else if (strpos ($ohreally, 'dumb')){return false;}  
   else {return true;}

или один preg_match?

if (preg_match('hello'||'i am'||'dumb', $ohreally)) {return false}   
   else {return true};

Я знаю, что код preg_match неверен, я был бы очень признателен, если бы кто-то мог предложить его правильную версию.

Спасибо!


Ответ

Пожалуйста, прочитайте, что сказал Клетус, и тест миддапарка сделал ниже. Я также проводил тестирование времени на разных струнах, длинных и коротких. с этими результатами

ЕСЛИ вам известна вероятность появления строковых значений, ЗАкажите их от наиболее вероятных до наименьших. (Я не заметил презентабельного отличия в заказе самого регулярного выражения, то есть между /hello|i am|dumb/ или /i am|dumb|hello/.

С другой стороны, в последовательном strpos вероятность имеет все значение. Например, если «привет» происходит 90%, «я» 7% и «тупой» 3% времени. Вы хотели бы организовать свой код, чтобы сначала проверить «привет» и выйти из функции как можно скорее.

мои микротайм-тесты показывают это.

для стогов сена A, B и C, в которых игла находится соответственно при первом, втором и третьем выполнении strpos (), времена следующие:

StrPos:
A: 0,00450 секунд // 1 strpos ()
B: 0,00911 секунды // 2 strpos ()
C: 0,00833 секунды // 3 strpos ()
C: 0,01180 секунд // 4 strpos () добавлен один дополнительный

и для preg_match:
A: 0,01919 секунд // 1 preg_match ()
B: 0,02252 секунды // 1 preg_match ()
C: 0,01060 секунд // 1 preg_match ()

как показывают цифры, strpos быстрее до 4-го выполнения, поэтому я буду использовать его вместо этого, так как у меня есть только 3 подпункта для проверки:)

Ответы [ 3 ]

7 голосов
/ 19 января 2010

Правильный синтаксис:

preg_match('/hello|i am|dumb/', $ohreally);

Я сомневаюсь, что в любом случае есть много, но меня не удивит, если метод strpos() будет быстрее в зависимости от количества строк, которые вы ищете. Производительность strpos() будет ухудшаться по мере увеличения количества поисковых запросов. Регулярное выражение, вероятно, будет, но не так быстро.

Очевидно, что регулярные выражения более мощные. Например, если вы хотите сопоставить слово «тупой», но не «тупой», то это легко сделать с помощью:

preg_match('/\b(hello|i am|dumb)\b/', $ohreally);

что гораздо сложнее сделать с strpos().

Примечание: технически \b - это граница слова нулевой ширины. «Zero-width» означает, что он не потребляет никакой части входной строки и границы слова, означает, что он совпадает с началом строки, концом строки, переходом от символов слова (цифры, буквы или подчеркивание) к не словесные символы или переход от несловесных к словесным символам. Очень полезно.

Редактировать: также стоит отметить, что вы используете strpos() неправильно (но многие люди совершают эту же ошибку). А именно:

if (strpos ($ohreally, 'hello')) {
  ...
}

не войдет в блок условий, если стрелка находится в позиции 0 в строке. Правильное использование:

if (strpos ($ohreally, 'hello') !== false) {
  ...
}

из-за жонглирования типа. В противном случае 0 конвертируется в false.

4 голосов
/ 19 января 2010

Сумасшедшая идея, но почему бы не протестировать оба 'n' тысячи раз в двух отдельных циклах, оба окруженные microtime ();и связанный с ним отладочный вывод.

На основе приведенного выше кода (с некоторыми исправлениями) для 1000 итераций я получаю что-то вроде:

strpos test:     0.003315
preg_match test: 0.014241

Таким образом, в данном случае (сограничения, обрисованные другими) strpos действительно кажется более быстрым, хотя и в значительной степени бессмысленным количеством .(Радость бессмысленной микрооптимизации и т. Д.)

Никогда не оценивайте, что вы можете измерить.

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

Это зависит от количества строк, которые вы хотите найти, и длины строки, которую вы ищете.

Вам необходимо поэкспериментировать с репрезентативным набором данных, чтобы выяснить, какое из них истинное (повторите операцию, скажем, 1000 раз и измерьте время задержки).

Кстати, я думаю, что вы ищете регулярное выражение '(привет | я | тупой)'

Кроме того, ваш код более многословен, чем должен быть:

return strpos($ohreally, 'hello') || strpos($ohreally, 'i am') || strpos($ohreally, 'dumb');

или

return preg_match('(hello|i am|dumb)',$ohreally);

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

С

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