- PVSM.RU - https://www.pvsm.ru -
В этой статье мы рассмотрим результаты нескольких бенчмарков, начиная с PHP 5 и вплоть до экспериментальной JIT-ветки (сейчас в разработке). На момент написания не было известно, появится ли до PHP 8 ещё какая-то основная версия, например PHP 7.2. Но логично предположить, что возможности экспериментальной ветки как минимум будут включены в PHP 8.
C момента своего появления в 1994-м язык PHP радикально изменился. Первые релизы представляли собой просто внешние CGI-программы, которые создавались во многом как личный проект Расмуса Лердорфа. С третьей версии PHP был серьёзно переработан, возникла группа разработчиков языка.
Благодаря расширяемости PHP 3 функциональность языка стремительно разрасталась. Появлялись базовые и дополнительные расширения, которые привносили новые функции в разные сферы: работу с сетью, парсинг, кеширование и поддержку баз данных.
Развивался и сам язык, в него внесли много улучшений. Появилась поддержка объектно ориентированных конструкций, таких как классы, интерфейсы, трейты, замыкания и т. д.
Но многим разработчикам этого было мало. С ростом популярности языка росли и требования к нему со стороны сообщества, в основном связанные с производительностью, масштабируемостью и более экономным потреблением памяти.
Почти 20 лет создатели языка прилагали огромные усилия, чтобы удовлетворять всевозможные требования. Хотя с появлением PHP 3 производительность существенно возросла, сколько-то серьёзные результаты язык смог продемонстрировать только с PHP 4, когда появился движок Zend.
В 2000-м были внедрены новые in-memory компилятор и модель исполнения (executor model). Это позволило вновь сильно поднять производительность PHP, нередко в 5—10 раз. В результате его начали всерьёз рассматривать как инструмент для создания веб-приложений и сайтов. И сегодня PHP достиг высот, которых никто не ожидал от этого языка, когда он появился.
Но взрывной рост популярности PHP лишь привёл к росту требований о повышении производительности. К счастью, у движка Zend прекрасный потенциал для модернизации.
Хотя PHP 5 не стал заметным шагом вперёд и в некоторых случаях был даже медленнее PHP 4, группа разработчиков Zend постоянно оптимизировала движок от релиза к релизу, в результате PHP 5.6 оказался быстрее в 1,5—3 раза.
Но главный рывок произошёл с выходом PHP 7 в декабре 2015-го. Через год была анонсирована версия 7.1, тоже получившая ряд улучшений.
В настоящее время разрабатывается очень многообещающая версия Zend. Она будет основана на версии из релиза 7.1, а когда именно выйдет, пока не объявлено. Так что сейчас это экспериментальная JIT-ветка.
Одна из главных интриг связана с Just-In-Time (JIT) компиляцией. Это методика преобразования кода в другой формат (нативный машинный код) прямо перед выполнением. Цель JIT — повысить скорость работы программ. Посмотрим, смогут ли разработчики сдержать обещание.
Для этой статьи использовались бенчмарки, измерявшие производительность обработки скриптов на чисто процессорных задачах, т. е. без операций ввода-вывода: обращений к файлам, подключений к сети или базе данных.
Применялись следующие бенчмарки:
Бенчмарки прогонялись на последних второстепенных релизах основных версий PHP:
Те же бенчмарки прогонялись и на всех промежуточных релизах, например между 5.3.0 и 5.3.29. Результаты красноречивы: релизы не демонстрировали заметных улучшений производительности. Улучшения отмечались только при переходах между основными версиями, например с PHP 5.4 на PHP 5.5 или с PHP 5.6 на PHP 7.
Это означает, что те же скрипты будут выполняться примерно с одной скоростью и на PHP 5.4.0, и на PHP 5.4.45.
Подробности о настройке хостовой системы, о выполнении конкретных бенчмарков и об интерпретировании результатов можно почитать тут [5].
По каждому бенчмарку приведены три значения:
Результаты прогона бенчмарков вы можете увидеть в таблице ниже.
(1) Бенчмарк не может выполняться на версиях до 5.3, потому что он использует свойства, которые ещё не были реализованы.
(2) Результаты в этой колонке немного смещены, потому что бенчмарку для работы нужен как минимум PHP 5.3. Их можно взять просто для справки, раз нельзя сравнить с PHP 5.0.
(3) Это модифицированная версия скрипта mandelbrot.php, который выполнялся слишком быстро в версии 7.1.0 в экспериментальной ветке, так что не получалось точно измерить скорость. Поэтому мы внутри скрипта выполняли сто вычислений, а не одно.
Конечно, чисто процессорные бенчмарки не позволяют оценить все аспекты производительности PHP. Данные могут быть нерепрезентативны. Тем не менее на основе этих данных можно сделать выводы:
PHP 5 гораздо производительнее, чем PHP 4. Движок Zend, лежащий в основе интерпретатора, был полностью переработан (Zend Engine 2), что открыло дорогу дальнейшим улучшениям. Здесь мы не будем освещать все различия между PHP 4 и PHP 5, вкратце пройдёмся лишь по вещам, внедрённым после PHP 5.0.
Ниже перечислены только те изменения, которые затронули ядро PHP. Более подробный список нововведений и изменений: PHP 5 [6] и PHP 7 [7].
switch()
require_once()
и include_once()
Большинство из этих улучшений относятся к движку Zend:
__call()
и __callStatic()
Прогон бенчмарков был чуть более сложным процессом, чем запуск Unix-команды time
, и проходил в несколько этапов:
С сделал выделенную систему с такими характеристиками:
Хотя система поставлялась с компилятором Gnu C 4.7.2, пришлось поставить более свежую версию: экспериментальная JIT-ветка должна компилироваться с помощью Gnu C 4.8 и выше.
Перед сборкой полных дистрибутивов был запущен скрипт configure со следующими параметрами:
--prefix=/usr/local/php
--disable-debug
--disable-phpdbg
--enable-mysqlnd
--enable-bcmath
--with-bz2=/usr
--enable-calendar
--with-curl
--enable-exif
--enable-fpm
--with-freetype-dir
--enable-ftp
--with-gd
--enable-gd-jis-conv
--enable-gd-native-ttf
--with-gettext=/usr
--with-gmp
--with-iconv
--enable-intl
--with-jpeg-dir
--enable-mbstring
--with-mcrypt
--with-openssl
--enable-pcntl
--with-pdo-mysql=mysqlnd
--with-png-dir
--with-recode=/usr
--enable-shmop
--enable-soap
--enable-sockets
--enable-sysvmsg
--enable-sysvsem
--enable-sysvshm
--enable-wddx
--with-xmlrpc
--with-xsl
--with-zlib=/usr
--enable-zip
--with-mysqli=mysqlnd
Конечно, я компилировал более старые версии, некоторые параметры требовалось отключить или заменить другими. Также не все расширения были доступны или могли быть скомпилированы.
Каждый бенчмарк запускался с помощью PHP CLI (Command-Line Interface) через специальный скрипт, который делал следующее:
1) С помощью функции microtime()
на лету модифицировал скрипт, чтобы изнутри измерять время его выполнения. После модифицирования скрипт выглядел так:
<?php
$__start__ = microtime( true );
/***
Здесь исходный код бенчмарка
***/
fprintf( STDERR, microtime( true ) - $__start__);
?>
Это делалось для того, чтобы обеспечить стабильность измерений скрипта изнутри, без изменения его поведения.
2) Далее шли два сухих прогона, чтобы исполняемые PHP-файлы и содержимое скрипта бенчмарка оказались в кеше ОС.
3) Скрипт выполнялся пять раз, сохранялись минимальное, максимальное и среднее время выполнения. В этой статье представлены только средние значения — «время выполнения скрипта».
Использовались такие настройки в php.ini:
engine = On
short_open_tag = Off
realpath_cache_size = 2M
max_execution_time = 86400
memory_limit = 1024M
error_reporting = 0
display_errors = 0
display_startup_errors = 0
log_errors = 0
default_charset = "UTF-8"
[opcache]
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=128
opcache.consistency_checks=0
opcache.huge_code_pages=1
// PHP 8/Next only
opcache.jit=35
opcache.jit_buffer_size=32M
Длительность выполнения измерялась с помощью Unix-команды time
. Пример выходных данных:
$ time php bench.php
real: 0m1.96s
user: 0m1.912s
sys: 0m0.044s
Значение real
— это время от вызова команды до её прерывания (пока не происходит возврата к командной строке).
Значение user
— время, потраченное на выполнение пользовательского кода (в данном случае — исполняемого PHP-файла).
Значение sys
— время, потраченное на выполнение кода ОС (kernel). Это значение должно быть минимальным, но может оказаться сильно больше представленного, если ваш код обращается, например, к медленным устройствам. Также на величину значения способна повлиять высокая загруженность ОС.
На системах в состоянии ожидания суммарное значение user + sys
должно быть очень близко к real
. В приведённом выше примере: user + sys = 1,956 с, real = 1,960 с
. Разница в 0,004 с связана не с нашим процессом, а с разными задачами ОС, например с диспетчеризацией.
Тот же скрипт был выполнен на высоконагруженной ОС при параллельном компилировании тремя разными PHP-версиями:
$ time php bench.php
real: 0m7.812s
user: 0m2.02s
sys: 0m0.101s
Как видите, уровень нагрузки сильно влияет на время выполнения (возможно, и на системное время). Поэтому я добавил в бенчмарк ещё одно значение — overhead
операционной системы. Это разница между полным временем выполнения (elapsed time
) и суммой пользовательского и системного времени.
Я удостоверился, чтобы во время прогона бенчмарков это значение в течение 99 % времени было меньше 100 миллисекунд, даже когда выполнение скриптов занимало десятки секунд.
Эта статья писалась при активной помощи Дмитрия Стогова. Он прояснил ряд моментов и рецензировал представленную здесь информацию.
Дмитрий был разработчиком расширения Turck MMCache, которое со времён PHP 4 может использоваться для кеширования PHP-опкодов в совместно используемой памяти. После этого Дмитрий начал работать над Zend, чем и занимается по сей день.
Также он когда-то инициировал создание PHPNG — того, что позднее превратилось в PHP 7. В работе над этой и последующими версиями с Дмитрием сотрудничали Никита Попов и Синьчэнь Хуэй (Xinchen Hui).
В создание PHP 5 внесли большой вклад Энди Гутманс, Зеев Сураски и Стас Малышев. Многих других разработчиков я не стану здесь перечислять, чтобы не загромождать статью.
В 2016-м исполнился 21 год со дня появления PHP — 8 июня 1995 г.
Чтобы отдать должное всем, кто так или иначе внёс свой вклад в развитие PHP, Питер Кокот с помощью Gource [9] создал анимационное видео. В нём рассказывается о развитии ключевых модулей PHP в течение всей жизни языка.
Питер Кокот [10] хорошо известен в PHP-сообществе. Он основал в Facebook [11] PHP Group [11], крупнейшую группу, посвящённую отдельному языку программирования. В ней состоят более 140 тыс. участников и 22 модератора. Создатель PHP Расмус Лердорф сказал: «В мире PHP ничего не происходит без движения сообщества». Надеюсь, эти слова будут вдохновлять вас.
Если вы не можете помочь развитию PHP с помощью написания кода на С, то можете выкладывать свои PHP-разработки на GitHub, PHP Classes, Packagist — куда угодно. Чем больше мест, где мы будем делиться друг с другом наработками, тем лучше.
Цель статьи — дать представление о производительности разных версий PHP, начиная с 5.0 и заканчивая свежайшей экспериментальной версией. Тестирование выполнялось с помощью известных бенчмарков. Также в статье приведён список улучшений, повысивших производительность различных версий PHP.
Автор: Mail.Ru Group
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/253021
Ссылки в тексте:
[1] bench.php: https://github.com/php/php-src/blob/master/Zend/bench.php
[2] micro_bench.php: https://github.com/php/php-src/blob/master/Zend/micro_bench.php
[3] mandelbrot.php: https://gist.githubusercontent.com/dstogov/12323ad13d3240aee8f1/raw/37fed3beb7e666b70e199bcf361af541b3c30d2d/b.php
[4] Экспериментальная JIT-ветка: https://github.com/zendtech/php-src
[5] тут: https://www.phpclasses.org/blog/post/493-php-performance-evolution.html#benchmarking-process
[6] PHP 5: http://php.net/ChangeLog-5.php
[7] PHP 7: http://php.net/ChangeLog-7.php
[8] VPS: https://www.reg.ru/?rlink=reflink-717
[9] Gource: http://gource.io/
[10] Питер Кокот: https://www.facebook.com/peterkokot
[11] в Facebook: https://www.facebook.com/groups/2204685680/
[12] Источник: https://habrahabr.ru/post/326696/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.