PHP: Выявляем узкие места в производительности сайта

Лирика

Каждый разработчик сайта рано или поздно сталкивается с проблемой оптимизации производительности своего проекта. Не важно по каким причинам (бурный рост, или же просто кривой код), и не важно на каком этапе (проектирование, продакшн) — нужно уметь выявлять узкие места и исправлять ситуацию. Что делать: добавлять кэш-сервера, разделять базу, оптимизировать запросы, править код и логику приложения? Решать Вам, но косвенно указать на узкое место поможет одно небольшое решение. Это обычный php-класс, который позволяет оценивать производительность любых фрагментов кода (по времени выполнения) и группировать полученные результаты. Решение с одной стороны простое до безобразия и его очень легко интегрировать в любой проект, с другой стороны может оказаться очень полезным инструментом при выявлении узких мест.

Физика


Итак, вот сам класс:
<?php
/**
* Class pageSpeed
*
* @version 0.1
* @author Andrew Musinzya <a.musinzya@gmail.com>
* @copyright © Andy2
* @license <a href="http://opensource.org/licenses/gpl-license.php">opensource.org/licenses/gpl-license.php</a> GNU Public License
*
*/

class pageSpeed
{

private $startTime = 0; // global php script execution time start
private $stopTime = 0; // global php script execution time end
private $execTime = 0;

private $tmpTimerStart = 0; // temporary timer used for local benchmarks such as sql queries, cache queries etc
private $tmpTimerStop = 0;
private $tmpTimer = 0;
private $tmpStarted = false;

private $curGroup = "";
private $curGroupDesc = "";

private $execStats = array(); // all benchmark statistics collected here

public $statistics = "\n\n\n";

}

}
?>


Теперь о том, как его использовать. Ближе к началу кода создаём объект:

$obj = new pageSpeed();


в самом конце кода вызваем метод finish:

$obj->finish();


После чего вся статистика доступна в свойстве statistics (в виде закоментированной html-строки).

echo $obj->statistics;


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

$obj->benchStart("Имя группы", "Описание действия");


и в конце фрагмента:

$obj->benchStop();


На этом все! Больше ничего не потребуется.

В качестве имени группы (метода benchStart) стоит выбрать имя некой логической темы, к которой относится исследуемый участок кода. Например, измеряя скорость выполнения SQL-запроса к БД в качестве имени группы можно использовать «SQL» или «SQL QUERIES», для запросов к кэшу — «MEMCACHE», к файловой системе — «FILES» и т.д. Важно понимать, для всех однородных операций лучше указывать одну и ту же группу. Таким образом можно будет определить производительность не только отдельной операции, но и всей подсистемы в целом.

В качестве описания действия можно указать любую строку, описывающую выполняемую операцию. Например «Executing SQL query 1», «Get user session data» или же сам SQL-запрос. Возможно, сейчас все выглядит запутанным и непонятным, но, думаю, следующий пример поставит все на свои места:

<?php

include 'serverside/core.speed.php'; // это наш класс

$obj = new pageSpeed();

// ------------------
$obj->benchStart("SQL QUERIES", "Getting user list");
echo "SELECT * FROM ...";
$obj->benchStop();

// ------------------
$obj->benchStart("SOME SHIT", "Put aaa into web universe");
echo "aaa" . "
";
sleep(1);
$obj->benchStop();

// ------------------
$obj->benchStart("SQL QUERIES", "Store session data");
for ($i=2;$i<20;$i++)
{
for ($j=1;$j<1745;$j++)
{
for ($k=1;$k<851;$k++)
{
$x = true;
}
}
}
$obj->benchStop();

// ------------------
$obj->benchStart("SQL QUERIES", "Get friends");
for ($i=2;$i<400;$i++)
{
$y = "Friends will be friends.";
}
$obj->benchStop();

// ------------------
$obj->finish();
echo $obj->statistics;

?>


В результате, в конце сгенерированного html будем иметь следующую статистику:



Единственное ограничение — не поддерживаются вложенные вызовы. Будьте внимательны.
Вот в принципе и все, чем хотел поделиться. Спасибо за внимание. Надеюсь, кому-нибудь да пригодится.


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.