Вы не зашли.
Главная » PHP » Тесты производительности
#1. Gemorroj Off (107)
Administrator
2008.03.10 15:03
Тесты производительности различных часто употребляемых конструкций PHP кода и отдельных функций.
Для тестов использовался скрипт прилагаемый к этой статье http://wapinet.ru/textbook/speed.htm
Тестировалось на PHP 5.2.4 + Apache 2.2.4 + WinXP SP2 (Denwer 3)
Задача: просмотр содержимого папки.
Результаты
Код:
span style="color: #0000BB"><?php// 10000 проходов// и так 5 раз// 7.0788// 7.2023// 7.4333// 7.0996// 7.1290$dir = "./";$scan = scandir($dir);foreach($scan as $f){//print $f;}---// 7.3640// 7.4306// 7.3660// 7.4751// 7.2902$dir = "./";$open = opendir($dir);while(($f = readdir($open)) != false){//print $f;}closedir($open);---// 7.9307// 8.1111// 8.4703// 8.0594// 8.3077$dir = "./";$hand = dir($dir);while(($f = $hand->read()) != false){//print $f;}$hand->close();---// 53.0054// 53.6093// 52.9707// 53.2398// 53.3150$dir = "*";$glob = glob($dir);foreach($glob as $f){//print $f;}?>
// print $f - закомментированно для более точных результатов тестирования
glob вне конкуренции smile данная функция работает НАМНОГО медленнее остальных, тестировавшихся.
Остальные более-менее равны по производительности. Встроенный класс dir работает, как видим,  чуть медленнее, видимо сказывается ООП.

Продолжение следует...
Отредактировано Gemorroj (2008.03.22 10:10)
#2. Gemorroj Off (107)
Administrator
2008.03.22 10:10
Код:
span style="color: #0000BB"><?php// 250000 проходов// 4.0472// 3.9551// 3.9555// 3.9487// 3.9205$test = null;if($test == null){// print $test;}// 3.9390// 3.9610// 3.9629// 3.9878// 3.9631$test = null;if($test == ''){// print $test;}// 3.9386// 3.9192// 3.9468// 3.9178// 3.9390$test = null;if($test === null){// print $test;}// 3.5278// 3.5305// 3.7416// 3.6181// 3.5312$test = null;if(!$test){// print $test;}// 7.3735// 6.6924// 6.6803// 6.7138// 6.9515$test = null;if(empty($test)){// print $test;}// 7.0340// 6.7897// 6.8383// 6.7610// 6.8296$test = null;if(isset($test)){// print $test;}?>
Интересный момент, не точная проверка на соответствие, в данном тесте, выполняется столько же, сколько и точная (== и ===).
Так же код с применением isset или empty работает заметно медленнее, это связано с тем, что вызываются функции, а в остальных случаях для проверки работают операторы сравнения, которые по определению быстрее.
Из всех приведенных примеров кода, быстрее работает код с применением отрицания (!)
Отредактировано Gemorroj (2008.03.22 12:12)
#3. Gemorroj Off (107)
Administrator
2008.03.22 11:11
вот еще интересная инфа, взята из комментариев к CURL функциям на php.net smile
Calculating 50 queries to http://www.flickr.com/.
cURL took 9.550734 seconds.
file_get_contents() took 10.878360 seconds.

Calculating 50 queries to http://www.yahoo.com/.
cURL took 4.729566 seconds.
file_get_contents() took 10.443786 seconds.

Calculating 50 queries to http://www.ebay.com/.
cURL took 46.348250 seconds.
file_get_contents() took 52.685604 seconds.

Calculating 50 queries to http://www.godaddy.com/.
cURL took 1.505460 seconds.
file_get_contents() took 37.154304 seconds.

Calculating 50 queries to http://www.php.net/.
cURL took 13.136836 seconds.
file_get_contents() took 17.981879 seconds.


другими словами CURL неизбежно быстрее чем file_get_contents
#4. Helqg Off (2)
Участник
2008.03.22 12:12
А проверка на пустоту empty()?
Стране нужны автобусы!
#5. Gemorroj Off (107)
Administrator
2008.03.22 12:12
да, точно smile не подумал, щас исправлюсь)
#6. Helqg Off (2)
Участник
2008.03.23 09:09
Да просто я всегда ей проверяю, хотелось бы быть уверенным в ее использовании.
Стране нужны автобусы!
#7. Gemorroj Off (107)
Administrator
2008.04.20 13:01
сравнивал mysql_fetch_assoc, mysql_fetch_array и mysql_fetch_row
тестировал следующим образом, 1 раз запускается этот код
Код:
span style="color: #0000BB"><?php// Хост, логин, пароль$con = mysql_connect('localhost','root','') or die ('Ошибка подключения к базе данных!');// Кодировкаmysql_query('SET NAMES `utf8`');// Имя БДmysql_select_db('gbs',$con);$q = mysql_query('SELECT * FROM `users`');?>
в таблице users 183 записи, состоит из 22 колонок.
далее 250000 раз запускалась одна из тестировавшихся функций.

вот что в результате имеем
Код:
$a = mysql_fetch_row($q);
4.9316
4.9642
4.9255
5.0077
4.9354
 
$a = mysql_fetch_assoc($q);
5.1141
5.0620
5.1188
5.0473
5.0907
 
$a = mysql_fetch_array($q);
5.1535
5.1544
5.2150
5.1027
5.2089
Если с mysql_fetch_row и mysql_fetch_assoc все более-менее понятно (mysql_fetch_row чуть быстрее, т.к. создает нумерованный массив, а не ассоциативный), то почему mysql_fetch_array практически не уступает mysql_fetch_assoc не совсем понятно. Ведь mysql_fetch_array создает целых 2 массива, и как мне казалось должна прилично уступать по скорости. Ан нет. Как это обьяснить без понятия.
#8. Helqg Off (2)
Участник
2008.04.20 21:09
там написанно не 2 массива, а массив с двойными индексами. Че это такое меня спрашивать не надо.
Стране нужны автобусы!
#9. Gemorroj Off (107)
Administrator
2008.06.23 12:12
Теперь Win XP SP3 wink
Вобщем страшное дело...
Код:
span style="color: #0000BB"><?php// 250000 проходовif(1)print '';/*2.81532.87822.92932.78122.81512.79462.82552.85112.82742.8898*/if(1){print '';}/*3.23253.22893.29253.23093.21443.26043.36183.24813.22013.2240*/?>
воооот...
даже не знаю что сказать( расстройство прям ='(
#10. Helqg Off (2)
Участник
2008.06.24 10:10
для 25 тысяч не фатальна 1 секунда
Стране нужны автобусы!
#11. Gemorroj Off (107)
Administrator
2008.06.24 12:12
250 тысяч smile
но сам факт... sad
#12. Helqg Off (2)
Участник
2008.06.24 18:06
250!!! А собственно нафига они там скобки то...
Стране нужны автобусы!
#13. Gemorroj Off (107)
Administrator
2008.06.24 19:07
ну так для меня удобнее. без скобок для меня код становится абсолютно не читабельным. да и сами разработчики PHP рекомендуют использовать скобки везде. а вот на деле со скобками медленне получается код(
#14. Helqg Off (2)
Участник
2008.06.24 20:08
Кстати про читабельность. Ща прочитал- "Perl был основан на awk sed grep, и других средствах  UNIX , и в результате при работе с перл часто получается код только для записи( то есть через несколько месяцов вы его понять не сумеете)." А ты про скобки
Стране нужны автобусы!
#15. Gemorroj Off (107)
Administrator
2008.07.14 04:04
извечный спор, что быстрее, print или echo smile
500.000 проходов
Код:
span style="color: #0000BB"><?phpprint '';/*1.03411.04261.04401.03851.0431*/echo '';/*0.84390.83790.84870.83680.8507*/?>
вот такие результаты)
#16. denich Off (0)
Участник
2008.07.14 11:11
значит echo быстрее)
ska ska ska
#17. AntiKiller
Гость
2008.08.01 00:12
Я тут на сайтик наткнулся... Gemorroj, глянь... http://www.phpbench.com , если с инглишом дружишь(я думаю что дружишь wink ), почитай там... если не дружишь(или кто ещё глянет сайтик не знающий инглиша, перезагрузи страницу которая откроется пару раз...)..........
#18. Gemorroj Off (107)
Administrator
2008.08.01 12:12
Ага, здорово. Особенно поразило на сколько быстрее код если подсчет кол-ва итераций вынести из цикла. А так же использование функций для работы с массивами array_keys() / array_values()
#19. Gemorroj Off (107)
Administrator
2009.02.28 14:02
Кто-то просил потестить скорость работы операторов AND, &&, OR, ||.
Результаты приводить не буду, т.к. разницы в скорости вообще не заметил. 100.000 проходов с любым из этих операторов занимало около 1.6 секунды.
#20. Gemorroj Off (107)
Administrator
2009.03.01 18:06
Код:
span style="color: #0000BB"><?php//150.000 проходовiconv_substr('1',1);//1.8843//1.8550//1.8388//1.8268//1.8288mb_substr('1',1);//1.7029//1.6956//1.6940//1.7172//1.6928substr('1',1);//1.6691//1.6661//1.6394//1.6151//1.6076?>
Как видно, шустрее всех  substr, потом mb_substr и самая медленная iconv_substr
При чем, чем входящая строка больше, тем разница ощущается сильнее.
Вообще не совсем понятно, помему библиотеки (iconv и mbstring) имеющие по большей части одинаковое предназначение разделены на 2 библиотеки.
#21. LONGMAN Off (0)
Участник
2009.03.10 02:02
Интересно было бы сравнить ещё и while, do while, for и foreach
#22. Gemorroj Off (107)
Administrator
2009.03.10 02:02
по ссылке в первом посте достаточно много информации на этот счет. http://wapinet.ru/textbook/speed.htm думаю повторяться не стоит.
#23. LONGMAN Off (0)
Участник
2009.03.10 02:02
Да я знаю эти тесты от Бородина, но интересно будет ещё тесты именно на Windows XP SP3
#24. Gemorroj Off (107)
Administrator
2009.04.10 19:07
Теперь PHP 5.3

файла не существует
error_reporting(0);

file_get_contents("xxx");
16.7541
17.4581
17.4037
14.7361
14.7268

@file_get_contents("xxx");
17.8958
16.7447
16.2829
14.8839
14.8261
а теперь ставим error_reporting(2039);
50.000 проходов
file_get_contents("xxx");
294.0389

@file_get_contents("xxx");
7.6748
такое получается из-за забивания буфера ошибками.
#25. JInn Off (2)
Участник
2009.04.12 17:05
Я где то читал что при использовании знака @ код работает медленне в 7 раз... Врут?...
Как все таки сложно быть ботом...
#26. Gemorroj Off (107)
Administrator
2009.04.12 17:05
я тоже такое читал, поэтому и решил проверить. В случае с file_get_contents выходит врут.
#27. JInn Off (2)
Участник
2009.04.12 18:06
А можешь проверить с этим же значком, только истинное утверждение? Возможно в том случае, если не будет никаких ошибок, результаты будут другими?
Как все таки сложно быть ботом...
#28. Gemorroj Off (107)
Administrator
2009.04.19 15:03
10.000 проходов
file_get_contents(__FILE__);
// 6.7937
// 6.9678
// 6.5534
// 6.8022
// 6.7107

@file_get_contents(__FILE__);
// 7.1111
// 7.2268
// 6.8919
// 7.0816
// 7.0639
да, действительно, если файл существует, то подавление ошибок с помощью собаки замедляет работу.
#29. JInn Off (2)
Участник
2009.04.19 16:04
Примерно 0.3 секунды за 10000 проходов. Не так существенно, как говорят, но все равно прилично
Как все таки сложно быть ботом...
#30. Gemorroj Off (107)
Administrator
2009.05.03 17:05
Сегодня пол дня воевал со следующим SQL запросом
Код:
SELECT DISTINCT `links`.`id` , `links`.`id_user` , `links`.`link` , `links`.`link_text` , `links`.`timeout` , `links`.`timeout_ip` , `links`.`timeout_ip_browser`
FROM `links` , `users`
WHERE `links`.`id_user` <>0
AND `links`.`16_17` = "1"
AND `links`.`sunday` = "1"
AND `links`.`in` >0
AND `links`.`on_off` = "1"
AND `links`.`comp` = "1"
AND `users`.`ban` = "0"
ORDER BY `links`.`id` DESC;
Требовалось оптимизировать... Результатов выборки без DISTINCT примерно 80.000 с DISTINCT примерно 150.
Так вот скорость мягко говоря удручает. Более 2-х секунд на средненьком сервере.
Решилось следующим образом
Код:
SELECT `links`.`id` , `links`.`id_user` , `links`.`link` , `links`.`link_text` , `links`.`timeout` , `links`.`timeout_ip` , `links`.`timeout_ip_browser`
FROM `links` , `users`
WHERE `links`.`id_user` <>0
AND `links`.`16_17` = "1"
AND `links`.`sunday` = "1"
AND `links`.`in` >0
AND `links`.`on_off` = "1"
AND `links`.`comp` = "1"
AND `users`.`ban` = "0"
GROUP BY `links`.`id`
ORDER BY `links`.`id` DESC;
Совсем небольшие изменения в коде, а запрос выполняется примерно за 0.2 секунды. В принципе тоже не ахти, но прогресс все равно очень заметный. В 10 раз.
#31. JInn Off (2)
Участник
2009.05.06 03:03
Вот еще вопрос. Вывод текста с переменными. Есть три варианта.

1 - echo "text $aaa text";
2 - echo 'text '.$aaa.' text';
3 - echo "text ".$aaa." text";

В первом варианте интерпретатор должен проверять весь текст на $ и пробел, что и замедляет процесс. Это типа ищет переменную.
Во втором варианте проверка не идет (процесс быстрее), но используется конкатенация (даже две), что по идее должно замедлять процесс.
Третий вариант из области антивариантов и "Так писать не надо", так что его можно не иметь ввиду.
Собственно вопрос в том, какой из вариантов, 1 или 2, работает быстрее? Для чистоты эксперимента текст должен быть в двух вариантах. Небольшим - до 50 символов и большим - до 300 символов. Это связано с первым вариантом, там потому что поиск идет. В принципе может кто то и так знает результат?
Как все таки сложно быть ботом...
#32. Gemorroj Off (107)
Administrator
2009.05.06 11:11
ну здесь этот вопрос рассматривался http://wapinet.ru/textbook/speed.htm
правда было это очень давно и, вероятно , на php4. Чуть позже попробую потестить на php5.3
#33. JInn Off (2)
Участник
2009.05.06 18:06
Посмотрел... Скажем так - я в шоке... К тому, что увидел могу добавить, что
$x="test ".$test." test ".$test." test ".$test;
быстрее на 10% чем
$x="test ".$test." test ".$test." test ".$test."";
то есть если последнюю переменную не закрывать, то это хорошо. Не смог правда проверить с одинарными кавычками
Как все таки сложно быть ботом...
#34. Gemorroj Off (107)
Administrator
2009.09.04 16:04
PHP 5.3.1
30 тысяч проходов
Код:
span style="color: #0000BB"><?php// 0.5504// 0.5523// 0.5499// 0.5622// 0.5541$a = 1;switch($a){ case 2: break; case 3: break; default: break;}// 0.4459// 0.4513// 0.4421// 0.4456// 0.4510$a = 1;if($a == 2){}else if($a == 3){}else{}?>
Добавлено спустя   7 минут  18 секунд:
JInn написал:
Посмотрел... Скажем так - я в шоке... К тому, что увидел могу добавить, что
$x="test ".$test." test ".$test." test ".$test;
быстрее на 10% чем
$x="test ".$test." test ".$test." test ".$test."";
то есть если последнюю переменную не закрывать, то это хорошо. Не смог правда проверить с одинарными кавычками
а что здесь шокирующего? нафига делать эту лишнюю конкатенацию с пустой строкой?
#35. Akdmeh Off (9)
Участник
2009.09.05 11:11
Интересно, но как по мне, ради этого не стоит избегать switch, ведь там возможно без break; подключить сразу несколько условий, да и визуально кода немного меньше)
Желание стать программистом из-за того, что вам нравляться компьютерные игры-это все равно, что желание стать гинекологом из-за того, что вам нравиться сексwink
#36. Gemorroj Off (107)
Administrator
2009.09.05 11:11
Akdmeh, да, зачастую switch удобнее. Но если скорость критически важный параметр, то приходится жертвовать удобством. Я на этот switch обратил внимание когда профилировал Gmanager. Оказалось что одна совсем ничем не примечательная функция определения расширения файла, занимает приличную долю ремени. Тем более что вызывается несколько раз в цикле. Пришлось отказаться от switch и переписать на if / elseif / else. Немного, но прирост производительности это дало.
#37. Akdmeh Off (9)
Участник
2009.09.05 13:01
Конечно, в циклах это бывает важно.
Кст, сравни у себя mb_substr и iconv_substr - интересно что у тебя выйдет.
Желание стать программистом из-за того, что вам нравляться компьютерные игры-это все равно, что желание стать гинекологом из-за того, что вам нравиться сексwink
#38. Gemorroj Off (107)
Administrator
2009.09.05 14:02
ок smile
Кстати, сейчас искал самый быстрый способ прохода по папке, без подпапок. Вероятно это достигается следующим способом:
Код:
span style="color: #0000BB"><?php$arr = array_diff(scandir('directory/', 0), array('.', '..'));?>
Пробовал в т.ч. новые итераторы, но с ними как минимум в 3 раза медленнее.
#39. Gemorroj Off (107)
Administrator
2009.09.05 14:02
iconv_substr быстрее примерно на треть.
100000 проходов
Код:
span style="color: #0000BB"><?php// 3.5349// 3.6812// 3.6436$a = "";iconv_substr($a, 0, 6, "UTF-8");// 5.7895// 5.8432// 5.8222$a = "";mb_substr($a, 0, 6, "UTF-8");?>
Такая же ситуация, если переменной $a присвоить какую-нибудь длинную строку.
Нужно отметить, что многое зависит от кодировки. Если у mb_substr стоит какая-нибудь однобайтовая кодировка, а у iconv_substr мультибайтовая, то естественно mb_substr выиграет.
#40. AND Off (11)
Участник
2009.11.06 22:10
MySQLi. Запрос с подготовленным выражением и без него.
Код:
span style="color: #0000BB"><?php$db = new Mysqli('localhost', 'root', '', 'test') or die('Can not connect to MySQL');$prepare = true;$integer = 1234567890;$string = 'dgjmnvyuoplhgdenjhtrmnfqskytkgoyhjkdfmdigjewruytgrehguhksjgijerpoiwhgjeijgewyewyhlnjkbgsyigbvydbwg';$start = microtime(true); if($prepare) { $stmt = $db->prepare('INSERT INTO test (`integer`, `string`) VALUES (?, ?)'); $stmt->bind_param('is', $integer, $string); for($i = 0; $i < 10000; $i++) { $stmt->execute(); } $stmt->close(); // 10000 проходов // 5.50247 // 5.46265 // 5.59152 // 1 проход // 0.00141 // 0.00125 // 0.00172}else { for($i = 0; $i < 10000; $i++) { $db->query('INSERT INTO test (`integer`, `string`) VALUES ('.intval($integer).', "'.$db->real_escape_string($string).'")'); } // 10000 проходов // 6.11369 // 6.08014 // 6.16883 // 1 проход // 0.00082 // 0.00106 // 0.00067}echo round(microtime(true) - $start, 5);$db->close();?>
#41. AND Off (11)
Участник
2009.11.12 16:04
PHP: красота кода сказывается на производительности
PHP: красота кода сказывается на производительности: часть 2
Интересные статьи smile
#42. Gemorroj Off (107)
Administrator
2009.11.12 19:07
действительно. спасибо.
Страниц: 13 4 5 Все
Главная
WEB
PunBB Mod v0.6.2
0.034 s