- Время выполнения скрипта PHP и потребляемая память
- Время выполнения скрипта
- Способ #1
- Способ #2
- Способ #3
- Способ #4
- Класс для получения времени выполнения скрипта
- Объем использованной памяти
- Конвертация результата в килобайты и мегабайты
- Время выполнения скрипта и объём потреблённой памяти
- Время выполнения скрипта и объём потреблённой памяти в Yii2
- How can I measure the speed of code written in PHP? [closed]
- 10 Answers 10
- Как тестировать производительность PHP
- Свой тест производительности ¶
- Всё познаётся в сравнении ¶
Время выполнения скрипта PHP и потребляемая память
Несколько способов узнать время выполнения скрипта PHP и затраченный объем памяти при выполнении этого скрипта.
Время выполнения скрипта
Способ #1
Функция microtime() с переданным значением true возвращает число секунд, прошедших с полуночи 01.01.1970 , причём это значение подсчитано до сотых долей секунды. Затем идёт сам скрипт (исполняемый код), который мы и проверяем. В последней строкой будет разница между текущим временем (после выполнения скрипта) и тем, что мы зафиксировали при старте скрипта. Разница времени после выполнения скрипта и времени до начала его работы, и есть время выполнения скрипта.
$start = microtime(true); // исполняемый код . echo '
==============================================================='; echo 'Время выполнения скрипта: ' . (microtime(true) - $start) . ' sec.';
Время выполнения скрипта: 0.16499996185303 sec.
Способ #2
Можно вместо $start = microtime(true) брать значение из переменной $_SERVER[‘REQUEST_TIME_FLOAT’] , которая содержит время запроса к серверу. Вычисление времени выполнения происходит за исполняемым кодом.
// исполняемый код . $time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']; echo $time . ' sec.';
Способ #3
Если на сервере установлен Xdebag :
// исполняемый код . echo xdebug_time_index() . ' sec.';
Способ #4
Можно подсчитать среднее значение выполнения скрипта и записать результат в логи:
$start = microtime(true); // исполняемый код . $time = round(microtime(true) - $start, 3); $f = fopen('time.log', 'a'); fwrite($f, $time . PHP_EOL); fclose($f); $log = file('time.log'); $result = round(array_sum($log) / count($log), 3); echo $result . ' sec.';
Класс для получения времени выполнения скрипта
Очень простой класс, который можно использовать для получения времени выполнения скрипта PHP. Имеет приватное статическое свойство $start , в которой будет храниться время начала выполнения скрипта и имеющее значение по умолчанию $start = .0 . Метод start() присваивает значение, которое вернула функция microtime свойству $start . Метод finish() возвращает разницу между текущим временем (после выполнения скрипта) и тем, что мы зафиксировали при старте скрипта (присвоили значение в $start ).
/** * Разница между текущей меткой времени и меткой self::$start * @return float */ public static function finish() < return microtime(true) - self::$start; >>
Timer::start(); // исполняемый код . echo 'Время выполнения скрипта: ' . Timer::finish() . ' sec.'; // =================================== // Пример использования класса Timer(). Заполним массив миллионом случайных чисел. Timer::start(); for ($i = 0; $i < 1000000; $i++) < $array[] = rand(0, 1000000); >echo 'Время выполнения скрипта: ' . Timer::finish() . ' sec.';
Объем использованной памяти
Функция memory_get_usage() возвращает количество памяти в байтах, которое было выделено PHP скрипту на данный момент.
Принцип очень похож на измерение времени выполнения скрипта, о котором речь шла выше. Здесь тоже есть, как бы, стартовое состояние и и разница между текущим состоянием и стартовым.
$memory = memory_get_usage(); // исполняемый код . echo 'Скушано памяти: ' . (memory_get_usage() - $memory) . ' байт';
В Xdebug есть функция xdebug_memory_usage() , которая возвращает тот же результат.
// исполняемый код . echo 'Скушано памяти: ' . xdebug_memory_usage() . ' байт';
Скушано памяти: 36018960 байт
Конвертация результата в килобайты и мегабайты
$memory = memory_get_usage(); for ($i = 0; $i < 1000000; $i++) < $array[] = rand(0, 1000000); >$memory = memory_get_usage() - $memory; // Конвертация результата в килобайты и мегабайты $i = 0; while (floor($memory / 1024) > 0) < $i++; $memory /= 1024; >$name = array('байт', 'КБ', 'МБ'); echo 'Скушано памяти: ' . round($memory, 2) . ' ' . $name[$i];
Время выполнения скрипта и объём потреблённой памяти
Timer::start(); $memory = memory_get_usage(); // начало исполняемого кода for ($i = 0; $i < 1000000; $i++) < $array[] = rand(0, 1000000); >// конец исполняемого кода $memory = memory_get_usage() - $memory; $name = array('байт', 'КБ', 'МБ'); $i = 0; while (floor($memory / 1024) > 0) < $i++; $memory /= 1024; >echo 'Время выполнения скрипта: ' . Timer::finish() . ' sec.
'; echo 'Скушано памяти: ' . round($memory, 2) . ' ' . $name[$i];
Время выполнения скрипта: 0.79099988937378 sec. Скушано памяти: 34 МБ
Время выполнения скрипта и объём потреблённой памяти в Yii2
Вывести время выполнения скрипта и объём потреблённой памяти в Yii2:
echo 'getElapsedTime()) , 'с. ' . round(memory_get_peak_usage()/(1024*1024), 2) . 'МБ -->';
How can I measure the speed of code written in PHP? [closed]
Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
How can I say which class of many (which all do the same job) execute faster? is there a software to measure that?
10 Answers 10
You have (at least) two solutions :
The quite «naïve» one is using microtime(true) tobefore and after a portion of code, to get how much time has passed during its execution ; other answers said that and gave examples already, so I won»t say much more.
This is a nice solution if you want to benchmark a couple of instructions ; like compare two types of functions, for instance — it’s better if done thousands of times, to make sure any «perturbating element» is averaged.
Something like this, so, if you want to know how long it take to serialize an array :
$before = microtime(true); for ($i=0 ; $i $after = microtime(true); echo ($after-$before)/$i . " sec/serialize\n";
Not perfect, but useful, and it doesn’t take much time to set up.
The other solution, that works quite nice if you want to identify which function takes lots of time in an entire script, is to use :
- The Xdebug extension, to generate profiling data for the script
- Software that read the profiling data, and presents you something readable. I know three of those :
- Webgrind ; web interface ; should work on any Apache+PHP server
- WinCacheGrind ; only on windows
- KCacheGrind ; probably only Linux and linux-like ; That’s the one I prefer, btw
To get profiling files, you have to install and configure Xdebug ; take a look at the Profiling PHP Scripts page of the documentation.
What I generally do is not enable the profiler by default (it generates quite big files, and slows things down), but use the possibility to send a parameter called XDEBUG_PROFILE as GET data, to activate profiling just for the page I need.
The profiling-related part of my php.ini looks like this :xdebug.profiler_enable = 0 ; Profiling not activated by default xdebug.profiler_enable_trigger = 1 ; Profiling activated when requested by the GET parameter xdebug.profiler_output_dir = /tmp/ouput_directory xdebug.profiler_output_name = files_names
(Read the documentation for more informations)
This screenshot is from a C++ program in KcacheGrind :
(source: sourceforge.net)You’ll get exactly the same kind of thing with PHP scripts 😉
(With KCacheGrind, I mean ; WinCacheGrind is not as good as KCacheGrind. )This allows you to get a nice view of what takes time in your application — and it sometimes definitly helps to locate the function that is slowing everything down ^^
Note that Xdebug counts the CPU time spent by PHP ; when PHP is waiting for an answer from a Database (for instance), it is not working ; only waiting. So Xdebug will think the DB request doesn’t take much time !
This should be profiled on the SQL server, not PHP, so.Hope this is helpful 🙂
Have fun !Как тестировать производительность PHP
Чтобы протестировать PHP, можно воспользоваться небольшой программой, которую я специально разработал и выложил на https://github.com/anton-pribora/php-benchmark. Для этого в консоли нужно выполнить комманду:
wget -qO- https://raw.githubusercontent.com/anton-pribora/php-benchmark/master/get_and_start_multitest.sh | bash
Программа произведёт серию испытаний и выдаст результат в виде таблицы, где будет указана операция и результат. Чем больше результат, тем лучше.
Testing PHP 5.6.40 . done Testing PHP 7.1.33 . done Testing PHP 7.2.24 . done Testing PHP 7.3.11 . done Testing PHP 7.4.0 . done Common KVM processor Units PHP 5.6.40 PHP 7.1.33 PHP 7.2.24 PHP 7.3.11 PHP 7.4.0 Simple math oper/sec 9,694,704 76,749,134 93,396,556 88,212,974 88,561,615 String concat oper/sec 14,455,661 21,454,010 25,068,760 26,464,926 25,779,646 Array + array oper/sec 641,446 907,981 969,094 1,192,167 1,110,056 Use array_merge oper/sec 478,435 792,310 1,232,440 2,024,396 1,891,306 Create empty object obj/sec 8,633,215 11,514,301 14,435,884 16,557,935 18,596,756 Foreach array iter/sec 23,658,767 59,150,973 63,562,887 69,153,163 69,161,292 Use array_walk iter/sec 7,621,713 12,974,978 13,745,403 14,070,210 14,051,297 Foreach array object iter/sec 7,719,552 13,601,564 13,440,295 13,929,112 13,550,944 Foreach simple object iter/sec 8,082,326 16,526,538 26,903,151 29,073,493 28,065,508 Call closure call/sec 10,452,182 24,726,970 28,977,637 30,060,239 29,499,678 Call object function call/sec 11,557,581 33,741,340 34,562,534 43,925,066 43,565,275 Call user function call/sec 12,487,432 33,463,550 41,150,988 46,615,301 43,979,755 Function rand call/sec 14,754,127 33,721,757 41,237,945 39,209,291 41,705,133 Function is_null call/sec 10,307,678 48,748,330 54,757,062 74,051,775 76,142,248 Function empty call/sec 38,389,411 46,019,203 50,974,064 59,100,247 70,081,321 Function isset call/sec 37,551,313 51,627,412 65,115,665 70,121,536 79,073,355
Свой тест производительности ¶
Также можно самостоятельно провести испытание. Для этого нужно сделать тестовый скрипт и придумать операцию для проверки.
Тестовый скрипт должен считать количество итераций в единицу времени. Таким образом рассчитывается скорость работы. Чем больше циклов успеет выполниться, тем лучше.
Вот пример тестирования работы с объектами (исходный код на pastebin):
$start = microtime(true); $cycles = 0; $elapsed = 0; $result = ''; do < $loops = 1000; $begin = microtime(true); do < // Тестируемая операция $result .= new A(array('foo' => 'bar')); > while (--$loops); $cycles += 1000; $elapsed += microtime(true) - $begin; > while (microtime(true) - $start < 1); printf("%s: %.0f cycle/sec, %s bytes, %s bytes/cycle\n", PHP_VERSION, $cycles / $elapsed, strlen($result), strlen($result) / $cycles);
Объект класса создаётся и тут же добавляется в результат в виде строки. Общее время выполнения теста будет чуть больше одной секунды. За эту секунду будет выполняться вложенный цикл do while, в котором будет срабатывать тестируемая операция. Такая вложенность нужна, чтобы уменьшить количество вызовов функции microtime.
class A < private $foo; private $bar; private $baz; private $bee; public function __construct($array) < foreach($this as $prop => $value) < if ( isset($array[$prop]) ) < $this-> = $array[$prop]; > > > public function __toString() < $result = array(); foreach($this as $prop => $value) < $result[] = $prop .': '. $this->; > return join("\n", $result); > >
Если запустить код, то выведется примерно следующее:
% php test.php 5.4.45-0+deb7u2: 107945 cycle/sec, 2808000 bytes, 26 bytes/cycle
Сто семь тысяч циклов в секунду! Неплохой результат.
Всё познаётся в сравнении ¶
На моём тестовом ноутбуке скомпилированы разные версии PHP. Я провёл тест на всех версиях:
% ls ./php-bin/php-* | xargs -I% sh -c '% test.php' 5.0.5: 111200 cycle/sec, 1344000 bytes, 12 bytes/cycle 5.1.6: 205900 cycle/sec, 2472000 bytes, 12 bytes/cycle 5.2.17: 96063 cycle/sec, 2522000 bytes, 26 bytes/cycle 5.3.29: 101803 cycle/sec, 2652000 bytes, 26 bytes/cycle 5.4.45: 110970 cycle/sec, 2886000 bytes, 26 bytes/cycle 5.5.33: 108943 cycle/sec, 2834000 bytes, 26 bytes/cycle 5.6.19: 116854 cycle/sec, 3042000 bytes, 26 bytes/cycle 7.0.4: 165556 cycle/sec, 4316000 bytes, 26 bytes/cycle 7.1.0-dev: 173207 cycle/sec, 4524000 bytes, 26 bytes/cycle
Из результатов видно, что начиная с версии 5.2 изменилась работа со строками, а самый производительный оказалась версия 5.1. Также видно, что после изменений в версии 5.2 производительность упала в два раза. Седьмые версии показывают увеличение производительности примерно в полтора раза по сравнению с 5.6.
© 2023 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.