
Почти три недели назад был анонсирован новый проект от Facebook. Он называется HipHop-PHP.
Для широкой публики исходные коды стали доступны лишь сутки назад.
HipHop был создан для улучшения производительности Facebook. Он преобразует PHP код в C++ код и комплирует его с помощью g++. HipHop доступен под opensource лицензией.
В данной статье описан процесс сборки HipHop из исходных кодов и его использование.
Процесс сборки
1. Клонируем репозиторий
$ git clone git://github.com/facebook/hiphop-php
2. Устанавливаем необходимые библиотеки
Установите неоходимые библиотеки, указанные в http://wiki.github.com/facebook/hiphop-php/building-and-installing. Обратите внимание на минимальные версии.
Замечания:
- Для TBB(Thread Building Blocks) минимальная версия 2.2, хоть это и не написано
- Необходимо пересобрать libcurl и libevent с патчами от разработчиков
Если увидели сообщение "struct evhttp_request has no member named ext_method" — значит, у вас не пропатченный libevent - Мне также потребовалось установить Google Perftools
3. Устанавливаем библиотеку libmbfl
$ cd hiphop-php
$ git submodule init
$ git submodule update
4. Настраиваем переменные окружения
$ export HPHP_HOME=`pwd`
$ export HPHP_LIB=`pwd`/bin
5. Перед сборкой
HipHop для сборки использует cmake. В исходном скрипте некоторые библиотеки были пропущены.
Чтобы это исправить, устанавливаем патч:
$ curl sparcs.kaist.ac.kr/~tinuviel/hiphop/cmake-missing-library.diff | patch -p1
6. Если у вас 32-битная система
HipHop изначально написан под 64-битную архитуктуру. Если у вас 32-битная, то нужно установить патчи:
$ curl sparcs.kaist.ac.kr/~tinuviel/hiphop/src-util-hash-long-long.diff | patch -p1
$ curl sparcs.kaist.ac.kr/~tinuviel/hiphop/src-cpp-base-ssize_t.diff | patch -p1
$ curl sparcs.kaist.ac.kr/~tinuviel/hiphop/src-lib-format-string.diff | patch -p1
7. Сборка
$ cmake .
и еcли нет ошибок, то
$ make
Дополнение для пользователей Debian, Ubuntu и других
Процесс установки хорошо описан здесь, но не забудьте про патчи для 32-битной системы.
Запуск
Создадим в папке src/hphp файл index.php, с содержимым
- <?php
- echo 'Hello HipHop';
- ?>
Компилируем и запускаем:
$ time ./hphp index.php --keep-tempdir=1 --log=3 running hphp... creating temporary directory /tmp/hphp_71TLF1 ... parsing inputs... parsing ./index.php... parsing inputs took 0'00" (6 ms) (null) pre-optimizing... pre-optimizing took 0'00" (0 ms) (null) inferring types... inferring types took 0'00" (0 ms) (null) post-optimizing... post-optimizing took 0'00" (0 ms) (null) creating CPP files... creating CPP files took 0'00" (213 ms) (null) compiling and linking CPP files... compiling and linking CPP files took 1'30" (90733 ms) (null) running executable /tmp/hphp_71TLF1/program --file index.php... Hello HipHopall files saved in /tmp/hphp_71TLF1 ... running hphp took 1'31" (91747 ms) (null) real 1m31.791s user 1m21.157s sys 0m6.500s
В папке /tmp/hphp_71TLF1 находится довольно интересное содержимое:
$ ls -l /tmp/hphp_71TLF1/ итого 25152 -rw-r--r-- 1 20673 Фев 21 12:19 CMakeCache.txt drwxr-xr-x 6 4096 Фев 21 12:21 CMakeFiles -rw-r--r-- 1 1558 Фев 21 12:19 cmake_install.cmake -rw-r--r-- 1 2518 Фев 21 12:19 CMakeLists.txt -rw-r--r-- 1 18343 Фев 21 12:19 Makefile drwxr-xr-x 2 4096 Фев 21 12:19 php -rwxr-xr-x 1 25653366 Фев 21 12:21 program drwxr-xr-x 2 4096 Фев 21 12:19 sys $ ls -l /tmp/hphp_71TLF1/php итого 12 -rw-r--r-- 1 783 Фев 21 12:19 index.cpp -rw-r--r-- 1 415 Фев 21 12:19 index.fw.h -rw-r--r-- 1 475 Фев 21 12:19 index.h
Cодержимое файла /tmp/hphp_71TLF1/index.c:
- #include <php/index.h>
- #include <cpp/ext/ext.h>
- namespace HPHP {
- ///////////////////////////////////////////////////////////////////////////////
- /* preface starts */
- /* preface finishes */
- Variant pm_php$index_php(bool incOnce /* = false */, LVariableTable* variables /* = NULL */) {
- FUNCTION_INJECTION(run_init::index.php);
- {
- DECLARE_GLOBAL_VARIABLES(g);
- bool &alreadyRun = g->run_pm_php$index_php;
- if (alreadyRun) { if (incOnce) return true;}
- else alreadyRun = true;
- if (!variables) variables = g;
- }
- DECLARE_GLOBAL_VARIABLES(g);
- LVariableTable *gVariables __attribute__((__unused__)) = get_variable_table();
- print("Hello HipHop");
- return true;
- } /* function */
- ///////////////////////////////////////////////////////////////////////////////
- }
В итоге скомплированная программа занимает целых 25 мегабайт.
Но помимо консольного режима, ее можно запустить в режиме веб-сервиса:
/tmp/hphp_71TLF1/program -m server -p 8080
и лицезреть приветсвие по адресу localhost:8080/index.php
Update. Оценка производительности
Конфигурация
Processor: 2x Intel® Pentium® Dual CPU T2370 @ 1.73GHz
Operating System: Debian GNU/Linux squeeze/sid
Apache/2.2.14 (Debian) with modphp
PHP 5.2.12-2 with Suhosin-Patch 0.9.7 (cli) (built: Jan 11 2010 17:30:06)
gcc version 4.4.3 20100108 (prerelease) (Debian 4.4.2-9)
Тест №1. «В лоб»
Запуск теста по мотивам хабратопика «Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб»
$ time php test.php answer: 39 real 0m32.308s user 0m32.258s sys 0m0.012s $ time /tmp/hphp_4C67mv/program --file test.php answer: 39 real 1m6.683s user 1m6.376s sys 0m0.168s $ g++ test.cpp $ time ./a.out answer: 39 real 0m1.758s user 0m1.744s sys 0m0.000s
Тест №2. Apache Benchmark
test.php:
<?php for($i = 0; $i < 1000; $i++) echo var_dump($_SERVER); ?>
Запуск HipHop в режиме веб-сервиса:
$ ./program -m server -p 8080 $ ab -n 1000 -c 5 http://127.0.0.1:8080/test.php Concurrency Level: 5 Time taken for tests: 67.019 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1166084000 bytes HTML transferred: 1166000000 bytes Requests per second: 14.92 [#/sec] (mean) Time per request: 335.096 [ms] (mean) Time per request: 67.019 [ms] (mean, across all concurrent requests) Transfer rate: 16991.44 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 2 Processing: 124 335 56.5 340 477 Waiting: 120 329 56.2 335 467 Total: 124 335 56.5 341 477
Запуск стандартного PHP c помощью Apache with modphp:
$ ab -n 1000 -c 5 http://127.0.0.1:80/test.php ... Concurrency Level: 5 Time taken for tests: 27.180 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1139183000 bytes HTML transferred: 1139000000 bytes Requests per second: 36.79 [#/sec] (mean) Time per request: 135.901 [ms] (mean) Time per request: 27.180 [ms] (mean, across all concurrent requests) Transfer rate: 40929.90 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.5 0 11 Processing: 52 136 32.2 137 216 Waiting: 0 3 1.5 3 17 Total: 52 136 32.2 137 216
Тест №3. Fractal Benchmark
Language | Time | Relative Speed |
---|---|---|
C gcc-4.4.3 | 0.05 seconds | 1.00 x |
HipHop | 0.18 seconds | 3.60 x |
Python 2.51 | 2.35 seconds | 47.00 x |
PHP 5.2.12 | 3.08 seconds | 61.60 x |
Выводы (личное мнение)
В двух тестах он оказался почти в два раза медленней стандартного PHP. Но не стоит забывать, что это всего лишь первая версия. Сам процесс сборки HipHop довольно тяжелый, а как таковой установки вообще нет. Установить его можно лишь для того, чтобы понять возможность трансформирования вашего PHP-приложения в C++. Явный минус HipHop — это отсутствие поддержки PostgreSQL (пока только MySQL) и отсутствие возможности подключить существующие PHP-модули. Надеюсь что у этого проекта все еще в впереди.
На этом все. Подробней про запуск HipHop можно прочитать здесь.
Также на GitHub есть два интересных форка:
- http://github.com/h4ck3rm1k3/hiphop-php/ — содержит дополнения для сборки deb-пакета
- http://github.com/sanxiyn/hiphop-php/tree/32bit — содержит уже установленные патчи для 32-битной версии