geektimes

Yii2 тестируем на HHVM

  • вторник, 18 ноября 2014 г. в 02:11:12
http://habrahabr.ru/post/243361/

Всем привет! Недавно зарелизился 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 прекрасно поддерживается. Думаю надо еще погонять на каких то небольших проектах. Посмотреть стабильность работы, не будет ли падать, если есть у кого-то опыт использования в продакшене было бы интересно послушать. Да, если у вас есть предложения по тестированию, пишите, попробуем прогнать. Всем Удачи!

Немного ссылок.:
Yii2
HHVM