Preg_match() vs strpos() для поиска соответствия?
Для проверки одиночного значения, какой из них является предпочтительным и почему?
$string == 'The quick brown fox jumps over the lazy dog';
if(strpos($string, 'fox') !== false){
// do the routine
}
# versus
if(preg_match('/fox/i', $string)){
// do the routine
}
Ответы
Ответ 1
Я бы предпочел strpos
over preg_match
, потому что регулярные выражения обычно более дороги для выполнения.
В соответствии с официальными документами php для preg_match
:
Не используйте preg_match()
, если вы только хотите проверить, есть ли одна строка содержащихся в другой строке. использование strpos()
или strstr()
, поскольку они будет быстрее.
Ответ 2
Если у вас есть сомнения, ориентир!
Очевидно, что мы могли бы найти лучший тест, чем этот, но просто чтобы доказать, что, когда он начнет увеличиваться, strpos()
будет довольно быстрым. (почти в 2 раза быстрее)
EDIT Позднее я заметил, что регулярное выражение нечувствительно к регистру. При повторном использовании этого параметра, используя stripos()
для более справедливого сравнения, результат составляет от 11 до 15, поэтому пробел сужается, но preg_match()
остается намного медленнее.
$str = "the quick brown fox";
$start1 = time();
for ($i = 0; $i<10000000; $i++)
{
if (strpos($str, 'fox') !== false)
{
//
}
}
$end1 = time();
echo $end1 - $start1 . "\n";
$start2 = time();
for ($i = 0; $i<10000000; $i++)
{
if (preg_match('/fox/i', $str))
{
//
}
}
$end2 = time();
echo $end2 - $start2;
// Results:
strpos() = 8sec
preg_match() = 15sec
// Results both case-insensitive (stripos()):
stripos() = 11sec
preg_match() = 15sec
Ответ 3
Никогда не используйте регулярные выражения, если это абсолютно необходимо. Накладные расходы, связанные с запуском и развертыванием двигателя регулярных выражений на такой строке, похожи на использование отбойного молотка вместо обычного молотка, сверла вместо отвертки.
У вас также есть большая погрешность с регулярными выражениями - несогласованными строками, неожиданными результатами и т.д. Придерживайтесь strpos, если strpos недостаточно гибко.
Ответ 4
Если вы уже используете preg_match
и preg_replace
повсюду в своем коде, то продолжайте и используйте его еще раз. Почему?
-
Производительность. Большая часть служебных данных, которые добавляет функция, находится в начальном времени загрузки движка, если вы уже заплатили эту цену, сделайте это достойным.
-
Читаемость. strpos(...)!==false
, хотя и быстрее, является невероятным бельмом.
Это одна из самых уродливых php-конструкций.
Использование ==
и
false
в нем действительно kludgy и смотреть трудно разобрать и хрупкой
редактирования.
Позор в основной команде за то, что не определил псевдоним типа strcontains()
для него, лет назад.
Теперь уже слишком поздно делать это, но тогда было бы хорошо.
Ответ 5
Итак, если кто-то считает, что этот тип вещей имеет какое-либо значение, следует принять во внимание, что он является константой в Big O. Другими словами, все вызовы базы данных, On ^ 2 или худшая активность. Время, затрачиваемое на эти команды низкого уровня, бессмысленно в большинстве случаев. Не говоря о том, что константы следует игнорировать, например, я реорганизовал код, который захватил изображения, потому что он делал это по одному за один секундой каждый, где он уменьшал его с 12 секунд до 1 секунды (с использованием запроса с несколькими завивателями). Дело в том, что встроенные команды более низкого уровня, структура кода более важна.
Ниже приведен код 10 миллионов звонков, а "сбережения" почти ничего.
function prof_flag($str)
{
global $prof_timing, $prof_names;
$prof_timing[] = microtime(true);
$prof_names[] = $str;
}
function prof_print()
{
global $prof_timing, $prof_names;
$size = count($prof_timing);
for($i=0;$i<$size - 1; $i++)
{
echo "<b>{$prof_names[$i]}</b><br>";
echo sprintf(" %f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
}
echo "<b>{$prof_names[$size-1]}</b><br>";
}
$l = 10000000;
$str = "the quick brown fox";
echo "<h3>Ran " .number_format($l,2) ." calls per command </h3>";
prof_flag("Start: stripos");
for ($i = 0; $i<$l; $i++)
if (stripos($str, 'fox') !== false) {}
prof_flag("Start: preg_match");
for ($i = 0; $i<$l; $i++)
if (preg_match('#fox#i', $str) === 1) {}
prof_flag("Finished");
prof_print();
Только значение для этого кода заключается в том, что он показывает классный способ записи времени, которое требуется выполнить для запуска lol
Ran 10,000,000.00 calls per command
Start: stripos
2.217225
Start: preg_match
3.788667
Start: ==
0.511315
Start: ucwords lol
2.112984
Finished
Ответ 6
Вы можете оптимизировать вышеуказанный preg_match
, написав:
preg_match('/(?>fox)/', $str)
это должно быть быстрее.