Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Скорость работы str_replace


Автор: KEM 17.3.2008, 13:31
В ходе очередных кодо-исправление возник такой вопрос!
Почему столь значительные разницы при выполнении казалось бы одинаковых операций?  smile 

Код

 for ($i=0; $i<500000;$i++){
    $bl_ar = str_replace(array("\r\n"," ",chr(9)),"",$bl_ar);
}
// Done: 6.978 sek


for ($i=0; $i<500000;$i++){
   while (list($ind, $val) = each($bl_ar)) $bl_ar[$ind] = str_replace(array("\r\n"," ",chr(9)),"",$val);
}
// Done: 1.187 sek


for ($i=0; $i<500000;$i++){
   foreach($bl_ar as $ind => $val){
     $bl_ar[$ind] =  str_replace(array("\r\n"," ",chr(9)),"",$val);
   }
}
// Done: 17.671 sek


Выходит вид while (list($ind, $val) = each($bl_ar)) на и более быстродействующий для обхода массива ?

Автор: Feldmarschall 17.3.2008, 13:40
В реальной жизни разница незаметна.

И при чем здесь "Скорость работы str_replace", хотелось бы знать.

Автор: merge 17.3.2008, 14:49
ты пробовал в разных php скриптах? всмысле не в одном? можнет он после первого вызова как-то оптимизировал массив?

Автор: awers 17.3.2008, 14:58
мало того что ворох орфографических ошибок, так и кроме str_replace функций не видешь?

Автор: KEM 17.3.2008, 16:11
Данные куски кода пробовал как вместе, так и раздельно, результат примерно одинаковый. 
Меня интересует почему вариант  
Код

 while (list($ind, $val) = each($bl_ar)) $bl_ar[$ind] = str_replace(array("\r\n"," ",chr(9)),"",$val);

является в  17 раз более быстродейстующим, чем
Код

 foreach($bl_ar as $ind => $val){
     $bl_ar[$ind] =  str_replace(array("\r\n"," ",chr(9)),"",$val);
   }

 

awers, вопрос нужно учиться читать внимательнее, а для флуда есть другие разделы smile 


Автор: Feldmarschall 17.3.2008, 16:26
Цитата(KEM @  17.3.2008,  16:11 Найти цитируемый пост)
Меня интересует почему вариант  

Ну если интересует - скачай исходный код, да посмотри - как реализован тот и другой вариант.
Вопрос ведь не имеет никакой практической ценности, а представляет чисто академический интерес.

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

Автор: SelenIT 17.3.2008, 16:29
KEM, а Вы уверены, что эти варианты на второй и последующих итерациях делают одно и то же? ;)

hint: найдите 1 отличие между конструкцией с while(each(...)), показавшей такой "феноменальный" результат, и подобной ей конструкцией в http://www.php.net/manual/ru/control-structures.foreach.php, приведенной в качестве эквивалентной для foreach-а.

Автор: KEM 17.3.2008, 17:06
Feldmarschall, ну почему же, с практической точки зрения давольно важно ели нужно максимально быстро обойти большие массивы данных.
SelenIT, конечно не одно и то же )
Для чистоты эксперимента,  если каждый элемент целочисленного массива увеличивать на 1, то вариант foreach при 5000 итераций явно отстаёт примерно в 22 раза!
Вот и весь академический интерес... smile 

Автор: SelenIT 17.3.2008, 17:17
KEM, еще бы ему не отставать. Он ведь честно проходит весь массив все полмиллиона раз. А вайл с листом несколько халявит...  smile 

Автор: awers 17.3.2008, 17:32
Цитата(KEM @  17.3.2008,  17:11 Найти цитируемый пост)
awers, вопрос нужно учиться читать внимательнее, а для флуда есть другие разделы  

Да, написано "Скорость работы str_replace", разве не так?

KEM, на phpclub.ru была статья по оптимизации. Там рассказано почему и что быстрее и в каких случаях стоит применять тот или иной вариант.

Автор: Canarat 17.3.2008, 17:38
KEM, 
Если не изменяет память, foreach копирует массив в памяти, именно с этим связаны его удобные свойства для программиста и некоторая медленность. Обрати внимание на синтаксис остальных циклов, и становится видно, что foreach необходимо совершать дополнительные операции с массивом(копирование, вычисление размеров) чтобы предоставить такой синтаксис.

Автор: SelenIT 17.3.2008, 18:50
KEM, подсказка "в лоб": каково быстродействие
Код

for ($i=0; $i<500000;$i++){
   reset($bl_ar); // внимательно читайте мануал! ;)
   while (list($ind, $val) = each($bl_ar)) $bl_ar[$ind] = str_replace(array("\r\n"," ",chr(9)),"",$val);
}

и чем это (как и foreach) отличается от изначального "казалось бы" самого быстрого варианта?

Автор: mishaSL 17.3.2008, 18:55
KEM, для полноты теста предлагаю свой вариант. Думаю он будет самый быстрый (если главное - это скорость):
Код

function testR(&$item, $key)
{
    $item = str_replace(array("\r\n"," ",chr(9)),"",$item);
}
array_walk($bl_ar, 'testR');

Автор: Feldmarschall 17.3.2008, 21:20
Цитата(KEM @  17.3.2008,  17:06 Найти цитируемый пост)
с практической точки зрения давольно важно ели нужно максимально быстро обойти большие массивы данных.

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

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

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

Автор: KEM 18.3.2008, 01:13
mishaSL, Ваш вариант оказался наиболее быстрым =)

SelenIT,   "reset($bl_ar); " да действительно косяк )

Feldmarschall, очень интересно было бы заслушать Ваш вариант на тему обработки списка e-mail из текстового файла, к примеру выборки по доменам?

awers, статью обязательно поищу и почитаю, т.к. вопрос очень интересует!

Подведу небольшой итог умозаключений в наглядной форме  smile 

Код

1 Done: 8.1106939315796
2 Done: 7.2879480838776
3 Done: 5.132677936554


Код

<?php

set_time_limit(90);

function tm_clc($st,$sp){
    $st = explode(" ", $st);
    $st = $st[1] + $st[0];
    $sp = explode(" ", $sp);
    $sp = $sp[1] + $sp[0];
    return $sp - $st;
}

function set_array(){
    for($i=0; $i<=2000000; $i++){
        $bl_ar[] = 1;
    }
    return $bl_ar;
}

################################################################################
$bl_ar = set_array();
$start = microtime();

 foreach($bl_ar as $ind => $val){
     $bl_ar[$ind] =  $val + 1;
   }

$stop = microtime();
echo "<br>1 Done: ".tm_clc($start,$stop)."<br>";
################################################################################
$bl_ar = set_array();
$start = microtime();

   while (list($ind, $val) = each($bl_ar)) $bl_ar[$ind] = $val + 1;

$stop = microtime();
echo "<br>2 Done: ".tm_clc($start,$stop)."<br>";
################################################################################
$bl_ar = set_array();
function testR(&$item, $key){ $item = $item + 1; }

$start = microtime();

   array_walk($bl_ar, 'testR');

$stop = microtime();
echo "<br>3 Done: ".tm_clc($start,$stop)."<br>";
################################################################################
?>


Господа...  smile 

Автор: SelenIT 18.3.2008, 01:22
Цитата(KEM @  18.3.2008,  01:13 Найти цитируемый пост)
списка e-mail из текстового файла

Так, может, Вам не str_replace, а обычный rtrim нужен? Он всяко побыстрее должен быть... И вообще, почему бы не использовать нормальную БД и извлекать любые выборки сразу в готовом виде?

Автор: KEM 18.3.2008, 01:29
это я к примеру сказал, мало ли случаев жёсткой привязки к конкретным условиям, тем более опять же работа "напрямую" с диском и памятью. быслрее работы через демоны БД.

Автор: SelenIT 18.3.2008, 01:51
Цитата(KEM @  18.3.2008,  01:29 Найти цитируемый пост)
 опять же работа "напрямую" с диском и памятью. быслрее работы через демоны БД.

Это бабка надвое сказала. Т.е. при сопоставимых условиях оно так, но, к примеру, выбор 100 значений из 100k по индексу явно будет побыстрее, чем перелопачивание всех этих 100k записей циклом. А если каждый раз грузить их все в память - то и подавно...

Автор: skyboy 18.3.2008, 01:51
KEM, если требуется "выборка по доменам", то один раз загнать в базу и поучать результаты с использованием индексов будет быстрее, чем "более быстрой работы с диском и памятью напрямую". потому что как только начинаются условия, сложнее, чем "просто выбрать", работа с массивами и памятью оказывается не такой уж и быстрой.

Добавлено через 1 минуту и 41 секунду
впрочем, давайте не оффтопить.
либо есть проблема и её надо решить(не исключая рефакторинга структуры и алгоритма), либо идем во "флейм" и там обсуждаем в духе "а что, если у меня нет СУБД" или "а у меня жесткая привязка к конкретным условиям" и т.д.

Автор: KEM 18.3.2008, 02:09
SelenIT, ну это не бабка сказала, на этом так сказать гугл стоился
Условностей и возможностей действительно много, и для их обсуждения есть отдельные разделы, не будем флудить

Автор: SelenIT 18.3.2008, 02:37
Цитата(KEM @  18.3.2008,  02:09 Найти цитируемый пост)
на этом так сказать гугл стоился

Уж точно не на полном переборе многотысячных массивов. Тем более на ПХП smile.

Автор: Feldmarschall 18.3.2008, 09:03
KEM, и какова конечная цель этой обработки?
Впрочем, можешь и не трудиться придумывать очередную сказку. Задачи в вебе делятся на две категории - выполняемые при обращении пользователя к сайту, и  запускаемые на регулярной основе в фоновом режиме.
Для обоих вариантов твои проблемы не актуальны. В первом случае мы обязаны избавиться от обработки больших объемов информации, а во втором нам эти копеечные затраты и вовсе по барабану. Учитывая же весовые коэффициенты задач (к примеру, парсинг нескольких букв и собственно отправка мейла) мы окончательно приходим к полной бессмысленности таких "измерений".


Автор: Feldmarschall 18.3.2008, 09:30
Цитата(KEM @  18.3.2008,  01:29 Найти цитируемый пост)
опять же работа "напрямую" с диском и памятью. быслрее работы через демоны БД. 

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

KEM, дело в том, что получение от "демона БД" десятка записей будет всяко быстрее самостоятельного чтения сотни тысяч строк напрямую с диска и памяти. То есть, "надвое сказала" - это только в случае, если мы свои сто тыщ запрашиваем у БД, а потом нова парсим сами, в своей памяти. Но даже в этом случае ещё не факт, что "сами будем быстрее". Но суть-то не в этом. БД нам нужна не как замена текстового файла, который мы читаем целиком. А именно как демон, у которого мы запрашиваем только нужную информацию. Которая составляет мизерную долю от общего объема хранимых данных.

Автор: KEM 18.3.2008, 11:16
Feldmarschall, ну что же вы так привязались к этому примеру с текстовым файлом ? файл же может быть не только текстовый)  Да и принципы работы СУБД я понимаю замечательно, для каждой задачи есть свои оптимальные пути решения и не всегда это БД, есть масса задач для которых собственные файлы, типизированные или нет, подходят куда лучше.

Цитата

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

Вообще согласен, но при фоновой обработке, тем более в условиях одной физики и приличного объема данных, эти "копеечные затраты" могут стать боком. Если вы можете увеличить производительность хотя бы на 5% делайте это!

Автор: Feldmarschall 18.3.2008, 12:18
Привязался я к примеру потому, что он высосан из пальца.
Потому, что в реальности таких примеров не существует.
Да, есть масса задач для которых собственные файлы, типизированные или нет, подходят, не "куда лучше", разумеется, а примерно так же, как и БД.
Но это не тот случай, когда в файле десятки тысяч строк!

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

Если же ты хочешь продолжать стоять на своем, то будь добр привести здесь реальный, практический случай. Только учти. Что беседуют с тобой здесь не мальчики, а профессионалы. Которые со всякими случаями сталкивались. И хорошо отличают реальность от фантазии. Поэтому или придумывай хорошенько, или сразу откажись от этой затеи. При этом задача должна быть реальной именно для тебя. Всякие гугли приводить в пример не надо - заранее предупреждаю - сядешь в лужу гораздо хуже.

Автор: KEM 18.3.2008, 12:40
))))))))
очень милые изречения, напомню что настоящий профессионал никогда себя таковым не считает. т.к. его личный опыт ему этого не позволит. А ещё профессионалы не переходят на личности т.к. они "не мальчики". Ну это так к слову, я не считаю нужным вам что то доказывать или обьснять, я высказал свою точку зрения и останусь при ней, т.к. ваша не аргументирована, если человек считает технологию которую ему дали единственным средством решения задач, это просто значит что он не видит и не хочет видеть дальше своего носа.
Прошу тему считать исчерпаной  smile 

Автор: Feldmarschall 18.3.2008, 16:35
Что и требовалось доказать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)