Поиск текста в строке?

Статус
В этой теме нельзя размещать новые ответы.

Андрейка

Senior pomidor developer
WP
мы предполагаем, что очень простая операция копирования при некотором размере превзойдет по времени оверхед от регулярки

PHP:
<?php 

class Timer 
{ 
    var $time_start; 

    function time() 
    { 
        return array_sum(explode(' ',microtime())); 
    } 

    function start() 
    { 
        $this->time_start = $this->time(); 
    } 

    function stop() 
    { 
        return $this->time() - $this->time_start; 
    } 
} 

function rnd_string( $length ) 
{ 
    $str = ''; 
    for( $i = 0; $i < $length; $i++ ) { 
        $str .= chr(ord('a')+mt_rand(0,25)); 
    } 
    return $str; 
} 
$search = rnd_string(2) ;
$text =  rnd_string(100000) ;

$timer = & new Timer(); 
$timer->start(); 
for ( $i = 0; $i < 1000; $i++ ) { 
    strstr($text,$search); 
} 
print "strstr: ".$timer->stop()."\n"; 

$timer->start(); 
for ( $i = 0; $i < 1000; $i++ ) { 
    preg_match('{'.$search.'}',$text); 
} 
print "preg_match: ".$timer->stop()."\n"; 
?>
 

andymc

Новичок
lorien
Так всегда и бывает.
Как языком почесать - на это все горазды,
а код написать реальный мало кто хочет или может(!)
 

lorien

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

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

Андрейка

Senior pomidor developer
lorien
повысить длину поискового фрагмента с двух до десяти ( я думаю, это более жизненный пример ), то strstr опять берёт лидерство.
шанс совпадения последовательности 10 случайных символов в 100Кб тексте сам прикинешь? или тервер это не жизненно?
 

lorien

Новичок
Ну, раз вы заговорили о жизненности, то следует заметить, что strstr имеет смысл использовать только для извлечения данных, а посему перепишем тест выше. Пускай и strsstr и preg_match аккумулируют найденные фрагменты в массиве.

PHP:
<?php 

class Timer 
{ 
    var $time_start; 

    function time() 
    { 
        return array_sum(explode(' ',microtime())); 
    } 

    function start() 
    { 
        $this->time_start = $this->time(); 
    } 

    function stop() 
    { 
        return $this->time() - $this->time_start; 
    } 
} 

function rnd_string( $length ) 
{ 
    $str = ''; 
    for( $i = 0; $i < $length; $i++ ) { 
        $str .= chr(ord('a')+mt_rand(0,25)); 
    } 
    return $str; 
} 

$search = rnd_string(2);

$timer = & new Timer(); 
$list = array();
$timer->start(); 
for ( $i = 0; $i < 100; $i++ ) { 
    $match = strstr(rnd_string(100000),$search);
    if ( false === $match ) {
        $list[] = $match;
    }
} 
print "strstr: ".$timer->stop()."\n"; 

unset($list);

$timer->start(); 
$list = array();
for ( $i = 0; $i < 100; $i++ ) { 
    if ( preg_match('{'.$search.'.*$}',rnd_string(100000),$match) ) {
        $list[] = $match[0];
    }
} 
print "preg_match: ".$timer->stop()."\n"; 
?>
Кстати, я заменил переменную $text обратно на вызов rnd_string т.к. это не жизненный пример - подавать 100 раз подряд одни и те же данные в функцию поиска, как это было сделано в вашем варианте теста.

Результаты:
[root@lorien /web]# php test2.php
strstr: 18.693923950195
preg_match: 19.66083407402
 

Андрейка

Senior pomidor developer
lorien
то следует заметить, что strstr имеет смысл использовать только для извлечения данных
я рад, что вы наконец-то это узнали

а посему перепишем тест выше
можешь переписывать, можешь не переписывать.. мне он не интересен, апсалютна..

это не жизненный пример - подавать 100 раз подряд одни и те же данные
опять не жизненный? почему это?)
 

lorien

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

Андрейка

Senior pomidor developer
lorien
Теперь хотелось бы увидеть ваши тесты, которые показывают, что strstr тормознее регекспов.
ваше утверждение?
Господа, я написал, что регекспы медленнее strstr, вы не согласны?
ваш вопрос?

ответ на ваш вопрос в контексте "поиск текста в строке" получен? еще у вас вопросы остались? если да - задавайте, не стесняйтесь

ЗЫ. то тервер, то надуманные случаи, когда строка из двух символов ищется 100 раз в неизменной строке
еще раз - вероятность найти 10 символов подряд в строке из 100000 примерно равна нулю..
а вот зачем нужно 1000 раз вызывать rnd_string я так от вас и не услышал. чем это более жизненно?
 

lorien

Новичок
Ок, дискуссия закончена, начинаем флейма, да?

>ваше утверждение?
Моё. Причём я подтвердил его первым и третим тестом.
>ваш вопрос?
>ответ на ваш вопрос в контексте "поиск текста в строке" получен?
Мои слова, только как это связано с тем, что для констатации наличия надо использовать strpos, а не strstr? Да никак.
Поиск текста в строке - двусмысленная фраза. Можно констатировать наличие или отсуствие(strpos) либо извлекать подстроку до конца(strstr), либо извлекать подстроку из "середины" текста( preg_match или strpos + strlen + substr. Я сказал, что strstr тормознее регеспов и привёл тест, вам его результаты не понравились и вы переписали этот тест, который вам "не интересен, апсалютна", исходя из тервера, так чтобы strstr облажалась копируя кучу подстрочек. Я вам привёл последний пример где и в том и том случае копируются подстрочки, как видите, strstr оказался чуть быстрее.

>а вот зачем нужно 1000 раз вызывать rnd_string я так от вас и не услышал. чем это более жизненно?
Затем что в реальности данные по которым ведётся поиск обычно разные на каждой итерации. Если же текст всегда один и тот же, то в дело вступает кака-то оптимизация. В общем, 100 итераций поиска по одной строке выполняются быстрее, чем по разным.

PHP:
<?php 

class Timer 
{ 
    var $time_start; 

    function time() 
    { 
        return array_sum(explode(' ',microtime())); 
    } 

    function start() 
    { 
        $this->time_start = $this->time(); 
    } 

    function stop() 
    { 
        return $this->time() - $this->time_start; 
    } 
} 

function rnd_string( $length ) 
{ 
    $str = ''; 
    for( $i = 0; $i < $length; $i++ ) { 
        $str .= chr(ord('a')+mt_rand(0,25)); 
    } 
    return $str; 
} 

class Text
{
    var $list;

    function Text()
    {
        $this->clear();
    }

    function clear()
    {
        unset($this->list);
        $this->list = array();
    }

    function add($text)
    {
        $this->list[] = $text;
    }

    function next()
    {
        return array_pop($this->list);
    }
}

$search = rnd_string(2);
$test_number = 10;
$timer = & new Timer();

$text = & new Text();
for( $i = 0; $i < $test_number; $i++ ) {
    $text->add(rnd_string(100000));
}

$timer->start(); 
$list = array();
for ( $i = 0; $i < $test_number; $i++ ) { 
    if ( preg_match('{'.$search.'.*$}',$text->next(),$match) ) {
        $list[] = $match[0];
    }
} 
print "preg_match: ".$timer->stop()."\n"; 

unset($list);

$text->clear();
$string = rnd_string(100000);
for( $i = 0; $i < $test_number; $i++ ) {
    $text->add($string);
}

$timer->start(); 
$list = array();
for ( $i = 0; $i < $test_number; $i++ ) { 
    if ( preg_match('{'.$search.'.*$}',$text->next(),$match) ) {
        $list[] = $match[0];
    }
} 
print "preg_match (one text): ".$timer->stop()."\n"; 
?>
 

hermit_refined

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

и вообще:
Поиск текста в строке - двусмысленная фраза. Можно констатировать наличие или отсуствие(strpos) либо извлекать подстроку до конца(strstr)
когда ищется(!) что-то в большом тексте, то нам никогда не нужен strstr(), ибо не нужна вся строка до конца. нам нужен либо лишь факт наличия, либо кусок текста, содержащий найденное. и там, и там - strpos().
так что поздно выкручиваться, просто убейтесь.
 

lorien

Новичок
угу, куда уж тут без мифов.
Это не миф, а наблюдение результатов предыдущего теста. Как по вашему, почему первый блок итераций отработал быстрее, чем второй?
когда ищется(!) что-то в большом тексте, то нам никогда не нужен strstr(), ибо не нужна вся строка до конца. нам нужен либо лишь факт наличия, либо кусок текста, содержащий найденное. и там, и там - strpos().
так что поздно выкручиваться, просто убейтесь.
И что? Я и говорю, что для каждой задачи своя функция. И с тем, что констатировать наличие подстроки нужно через strpos, а не strstr я в этом топике не разу не спорил. То есть, я решительно не понимаю, С КЕМ вы спорите, уж точно не со мной )
P.S.
Есть такая пословица "смотрим в книгу, видим фигу"
 

hermit_refined

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

уже этой вашей способностью делать выводы на совершенно пустом месте вы себя дискредитировали.
ну и выкладывать уйму тестов на тему strstr vs. preg_match, а потом говорить, что "констатировать наличие подстроки нужно через strpos, а не strstr я в этом топике не разу не спорил" - глупо.
ну т.е. терпимо, и не такое бывает, только гонор убавьте.
 

lorien

Новичок
они будут отличаться в ту или другую сторону при разных запусках.
Почему-то в ту сторону они отличаются в подавляющем количестве раз, нежели чем в иную, вы не находите?
уже этой вашей способностью делать выводы на совершенно пустом месте вы себя дискредитировали.
Ах, вот уже, значит, как называется наблюдение результатов тестов? Если вы считатете, что я не прав, то вам бы следовало привести разумную аргументацию, а не рассказывать сказки про мифы.
ну и выкладывать уйму тестов на тему strstr vs. preg_match, а потом говорить, что "констатировать наличие подстроки нужно через strpos, а не strstr я в этом топике не разу не спорил" - глупо.
ну т.е. терпимо, и не такое бывает, только гонор убавьте.
Глупо? А спорить с дураком, кем я по вашему мнению являюсь, не глупо? Ещё как глупо! Вот и не спортье ;-)
 

hermit_refined

Отшельник
А спорить с дураком, кем я по вашему мнению являюсь, не глупо?
вы не совсем дурак, просто не умеете признавать свои ошибки.
а ко второму лично я более нетерпим, чем к первому.
Почему-то в ту сторону они отличаются в подавляющем количестве раз, нежели чем в иную, вы не находите?
не знаю кто куда там отличается, но никто не обещал, что вероятностная плотность будет симметрична относительно среднего арифметического.
и, если уж на то пошло, реальным временем такие вещи вообще не измеряют.

короче, если вас интересует, кешируются ли как-то результаты - нет, не кешируются (в отличие от результатов компиляции шаблона).
хотите убедиться - смотрите исходники, а не медитируйте на миллисекундах.
 

lorien

Новичок
вы не совсем дурак, просто не умеете признавать свои ошибки.
а ко второму лично я более нетерпим, чем к первому.
Все мои посты кроме первого были с целью "спор ради спора", ну, то есть, чтобы пофлеймить, что мне, как вижу, удалось. Вот, бывает у меня иногда такое желание, что поделаешь ;-).

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

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

hermit_refined

Отшельник
замеры времени работы реального кода показывают, что один блок выполняется быстрее другого?
ok. напишите об этом статью.
Все мои посты кроме первого были с целью "спор ради спора", ну, то есть, чтобы пофлеймить, что мне, как вижу, удалось.
не-а. лишь неудачные попытки сохранить хорошую мину при плохой игре.
а так, да, удачи...
 

lorien

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

не-а. лишь неудачные попытки сохранить хорошую мину при плохой игре.
Ну, согласитесь, если бы я во втором посте написал, что под словами "Регекспы медленнее простых операций типа strstr", я имел в виду, что для простых операций поиска и извлечения подстрок есть специальные быстрые функции substr,strpos,strstr и т.д., и что preg_* надо использовать только тогда, когда требуется более мощная функциональность или когда это удобно и скорость выполнения кода не играет никакой роли, то флейма бы не получилось ;-)
 

StUV

Rotaredom
Тема закрыта.

Проблемы личного характера и бессмысленные споры между участниками не являются предметом обсуждения форума.
Обсуждайте их в привате.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху