Вы не зашли.
Главная » PHP » Тесты производительности
#1. Gemorroj Off (108)
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)
Задача: просмотр содержимого папки.
Результаты
Код:
<?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 (108)
Administrator
2008.03.22 10:10
Код:
<?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 (108)
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 (108)
Administrator
2008.03.22 12:12
да, точно smile не подумал, щас исправлюсь)
#6. Helqg Off (2)
Участник
2008.03.23 09:09
Да просто я всегда ей проверяю, хотелось бы быть уверенным в ее использовании.
Стране нужны автобусы!
#7. Gemorroj Off (108)
Administrator
2008.04.20 13:01
сравнивал mysql_fetch_assoc, mysql_fetch_array и mysql_fetch_row
тестировал следующим образом, 1 раз запускается этот код
Код:
<?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 (108)
Administrator
2008.06.23 12:12
Теперь Win XP SP3 wink
Вобщем страшное дело...
Код:
<?php
// 250000 проходов
 
if(1)
print '';
/*
2.8153
2.8782
2.9293
2.7812
2.8151
2.7946
2.8255
2.8511
2.8274
2.8898
*/
 
if(1){
print '';
}
/*
3.2325
3.2289
3.2925
3.2309
3.2144
3.2604
3.3618
3.2481
3.2201
3.2240
*/
?>
воооот...
даже не знаю что сказать( расстройство прям ='(
#10. Helqg Off (2)
Участник
2008.06.24 10:10
для 25 тысяч не фатальна 1 секунда
Стране нужны автобусы!
#11. Gemorroj Off (108)
Administrator
2008.06.24 12:12
250 тысяч smile
но сам факт... sad
#12. Helqg Off (2)
Участник
2008.06.24 18:06
250!!! А собственно нафига они там скобки то...
Стране нужны автобусы!
#13. Gemorroj Off (108)
Administrator
2008.06.24 19:07
ну так для меня удобнее. без скобок для меня код становится абсолютно не читабельным. да и сами разработчики PHP рекомендуют использовать скобки везде. а вот на деле со скобками медленне получается код(
#14. Helqg Off (2)
Участник
2008.06.24 20:08
Кстати про читабельность. Ща прочитал- "Perl был основан на awk sed grep, и других средствах  UNIX , и в результате при работе с перл часто получается код только для записи( то есть через несколько месяцов вы его понять не сумеете)." А ты про скобки
Стране нужны автобусы!
#15. Gemorroj Off (108)
Administrator
2008.07.14 04:04
извечный спор, что быстрее, print или echo smile
500.000 проходов
Код:
<?php
print '';
/*
1.0341
1.0426
1.0440
1.0385
1.0431
*/
 
echo '';
/*
0.8439
0.8379
0.8487
0.8368
0.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 (108)
Administrator
2008.08.01 12:12
Ага, здорово. Особенно поразило на сколько быстрее код если подсчет кол-ва итераций вынести из цикла. А так же использование функций для работы с массивами array_keys() / array_values()
#19. Gemorroj Off (108)
Administrator
2009.02.28 14:02
Кто-то просил потестить скорость работы операторов AND, &&, OR, ||.
Результаты приводить не буду, т.к. разницы в скорости вообще не заметил. 100.000 проходов с любым из этих операторов занимало около 1.6 секунды.
#20. Gemorroj Off (108)
Administrator
2009.03.01 18:06
Код:
<?php
//150.000 проходов
 
iconv_substr('1',1);
//1.8843
//1.8550
//1.8388
//1.8268
//1.8288
 
mb_substr('1',1);
//1.7029
//1.6956
//1.6940
//1.7172
//1.6928
 
substr('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 (108)
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 (108)
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 (108)
Administrator
2009.04.12 17:05
я тоже такое читал, поэтому и решил проверить. В случае с file_get_contents выходит врут.
#27. JInn Off (2)
Участник
2009.04.12 18:06
А можешь проверить с этим же значком, только истинное утверждение? Возможно в том случае, если не будет никаких ошибок, результаты будут другими?
Как все таки сложно быть ботом...
#28. Gemorroj Off (108)
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 (108)
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 (108)
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 (108)
Administrator
2009.09.04 16:04
PHP 5.3.1
30 тысяч проходов
Код:
<?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 (108)
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 (108)
Administrator
2009.09.05 14:02
ок smile
Кстати, сейчас искал самый быстрый способ прохода по папке, без подпапок. Вероятно это достигается следующим способом:
Код:
<?php
$arr array_diff(scandir('directory/'0), array('.''..'));
?>
Пробовал в т.ч. новые итераторы, но с ними как минимум в 3 раза медленнее.
#39. Gemorroj Off (108)
Administrator
2009.09.05 14:02
iconv_substr быстрее примерно на треть.
100000 проходов
Код:
<?php
// 3.5349
// 3.6812
// 3.6436
$a "";
iconv_substr($a06"UTF-8");
 
// 5.7895
// 5.8432
// 5.8222
$a "";
mb_substr($a06"UTF-8");
?>
Такая же ситуация, если переменной $a присвоить какую-нибудь длинную строку.
Нужно отметить, что многое зависит от кодировки. Если у mb_substr стоит какая-нибудь однобайтовая кодировка, а у iconv_substr мультибайтовая, то естественно mb_substr выиграет.
#40. AND Off (11)
Участник
2009.11.06 22:10
MySQLi. Запрос с подготовленным выражением и без него.
Код:
<?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) - $start5);
$db->close();
 
?>
#41. AND Off (11)
Участник
2009.11.12 16:04
PHP: красота кода сказывается на производительности
PHP: красота кода сказывается на производительности: часть 2
Интересные статьи smile
#42. Gemorroj Off (108)
Administrator
2009.11.12 19:07
действительно. спасибо.
Страниц: 13 4 5 Все
Главная
WEB
PunBB Mod v0.6.2
0.036 s