Всем привет! Недавно зарелизился Yii2 с кучей новых фич и поддержкой HHVM, разработчики говорят о совместимости в 99%. Попробуем завести все это дело и опробовать в действии на живых примерах, где будут выборки из БД, сериализация (десирализация) данных, json — encode, decode, работа с ActiveRecord. Но прежде немного о самой машине. HHVM — экспериментальная виртуальная машина от Facebook для исполнения и JIT компиляции PHP кода. За счет неё можно увеличить производительность в несколько, а то и пять — девять раз на ресурсозатратных задачах. Проект живет и активно развивается. По поводу выхода новых версий хорошо написано в статье на хабре.
Что было сделано, оптимизировано в HHVM:
— Поддержка функционала php 5.6 кроме некоторых функций вроде eval, create_function.
— Написан новый язык программирования Hack — php — подобный язык со статической типизацией.
— Переработан APC сache, альтернативу которому включает в себя HHVM, были убраны функции сериализации (десириализации), которые как известно, очень накладны по ресурсам.
— Ускорены функции по JSON кодированию данных, UTF8 / UTF16 преобразований.
— Менее затратный подсчет ссылок — каждая строка, массив или объект в php имеют счетчик ссылок, счетчик увеличивается, когда переменная связываться со значением, и уменьшаться когда переменная выходит из области видимости. Такие операции занимают значительное процессорное время. Был разработан отдельный компилятор, который стараются избежать подсчет ссылок, когда это не нужно.
— Улучшено распределение памяти — были оптимизированы проблемные места. Там где память выделяется и в дальнейшем не используется, она освобождается.
Установка HHVM:
В настоящее время доступна инсталляция пакетов и компиляция исходных кодов для всех популярных дистрибутивов.
Посмотреть поддержку можно здесь:
HHVM (версия 3.3.1) завелась без проблем из пакетов на Debian 7.7 и Ubuntu 14.04
wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
echo deb http://dl.hhvm.com/debian wheezy main | sudo tee /etc/apt/sources.list.d/hhvm.list
sudo apt-get update
sudo apt-get install hhvm
После установки создаеться файлик конфигурации /etc/nginx/hhvm.conf, в котором уже записаны базовые настройки для location. нам остается только создать хост для yii в /etc/nginx/sites-available/
server {
root /www/hhvm.re/public_html;
index index.html index.htm index.php;
server_name hhvm-yii.local;
include hhvm.conf;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ /.ht {
deny all;
}
}
Все, устанавливаем Yii привычным способом через composer.
Cтартуем hhvm, перезапускаем nginx.
HHVM должна запуститься. Если нет, то можно посмотреть логи /var/log/hhvm/error.log
Так же можно подкрутить конфигурацию php, в hhvm она своя /etc/hhvm/server.ini.
Время тестов.
Тестирование проводилось на стареньком 2х ядерном ноутбуке, amd 64, @ 1,9 ГГц 4 гб ОЗУ:
Debian 7.7,
Nginx 1.2.1,
MySQL 5.5.38
Одна конфигурация: php-fpm 5.6
Вторая: hhvm 3.3.1
Каждый тест будем запускать по 10 раз, вычисляя средние значения по отработанному времени.
1. Запуск Yii2 из коробки показал практически одинаковую производительность. Видимо, фреймворк и так достаточно легкий, чтобы что-то оптимизировать. Привет, WordPress )
2. Вывод 300 новостей с пагинацией и разными виджетами:
$newsList = new ActiveDataProvider([
'query' => News::find(),
'pagination' => [
'pageSize' => 30,
],
'sort' => false,
]);
3. А теперь возьмем данных побольше, например, 5к товаров, с прописанными связями к поставщикам, магазинам, и категориям. Выведем по 300 товаров на страницу, чтобы не мелочиться. Профит есть, но пока не такой как хотелось бы:
$productList = ActiveDataProvider([
'query' => Product::find()
->where([
'statusId' => 1,
]),
'pagination' => [
'pageSize' => 300,
],
'sort' => false,
]);
4. Стандартная задача. У нас 500 категорий. Подсчитать количество товаров к каждой категории. Конечно, результаты можно и в кэш положить и хранить count где-то в отдельном поле. Но нам вот хочется их в runtime отрабатывать, посмотрим:
$categoryList = ProductCategory::find()->all();
$listCount = [];
foreach ($categoryList as $category){
$listCount[] = Product::find()
->where(['id_category' => $category->id])
->count();
}
Тут результаты уже поинтереснее, прирост почти в 4 раза. Неплохо да?
5. Сериализация (десериализация) Например, захотели мы объекты товаров хранить в каком-нибудь Memcache. Посмотрим, с какой скоростью они будут запаковываться/ распаковываться. Операция бывает достаточно дорогая, не поспоришь, особенно на больших данных. Прирост в 3,67 раз:
$productList = Product::find()->all();
foreach ($productList as $product){
$serialize = serialize($product);
unserialize($serialize);
}
6. Часто приходиться кодировать/ декодировать данные в json. Особенно актуально для разных REST Api сервисов или выборку данных для Single Page Application. Обработка c HHVM впечатляет, быстрее в 5 раз:
$productList = Product::find()->all();
foreach ($productList as $product){
$encode = json_encode($product);
json_decode($encode);
}
7. Ну и напоследок попробуем создать модель, которая будет писать данные в Redis. Yii2 предоставляет нам прекрасную возможность для этого. Критично в задачах с частой записью, выборкой данных, где не имеет смысла кешировать данные:
for ($i=0; $i < 5000; $i++){
$customer = new Customer();
$customer->attributes = ['name' => $i];
$customer->save();
}
Таблица результатов:
Название теста | Yii2 php5-fpm (сек.) | Yii2 HHVM (сек.) | Прирост по скорости |
---|---|---|---|
1. Из коробки | 0,10 | 0,09 | 1,1 |
2. Вывод новостей | 0,17 | 0,16 | 1,06 |
3. Вывод 5к. товаров | 1,51 | 1,12 | 1,34 |
4. Подсчет товаров в категории | 2,82 | 0,63 | 3,61 |
5. Сериализация / Десериализация | 3,24 | 0,88 | 3,68 |
6. JSON (encode, decode) | 2,73 | 0,51 | 5,35 |
7. Redis (Model ActiveRecord) | 10,53 | 4,43 | 2,37 |
Ну, вот и все, результаты в цифрах и на лицо, в принципе достаточно не плохо, от HHVM остались только положительные впечатления, не надо никаких магических костылей и танцев, чтобы все это завести. Все что нужно в PHP и Yii прекрасно поддерживается. Думаю надо еще погонять на каких то небольших проектах. Посмотреть стабильность работы, не будет ли падать, если есть у кого-то опыт использования в продакшене было бы интересно послушать. Да, если у вас есть предложения по тестированию, пишите, попробуем прогнать. Всем Удачи!
Автор: itcoder