📜 ⬆️ ⬇️

PHP version performance comparison


In this article, we will look at the results of several benchmarks, starting with PHP 5 and up to the experimental JIT branch (currently in development). At the time of this writing, it was not known whether there would be another major version before PHP 8, for example PHP 7.2. But it is logical to assume that the capabilities of the experimental branch will at least be included in PHP 8.


Since its introduction in 1994, the PHP language has radically changed. The first releases were simply external CGI programs that were created largely as a personal project of Rasmus Lerdorf. Since the third version of PHP has been seriously reworked, there was a group of language developers.


Thanks to the extensibility of PHP 3, the language functionality has expanded rapidly. Basic and additional extensions appeared that introduced new functions in different areas: networking, parsing, caching and database support.


The language itself developed, and many improvements were made to it. There is support for object-oriented constructs, such as classes, interfaces, traits, closures, etc.
But this was not enough for many developers. With the growing popularity of the language, the demands on the community also increased, mainly related to performance, scalability, and more economical memory consumption.


For almost 20 years, the creators of the language have made great efforts to meet all sorts of requirements. Although with the advent of PHP 3, the performance has increased significantly, the language was able to demonstrate some serious results only with PHP 4, when the Zend engine appeared.


In 2000, new in-memory compiler and execution model (executor model) were introduced. This allowed again to greatly increase the performance of PHP, often 5-10 times. As a result, it began to be seriously considered as a tool for creating web applications and sites. And today, PHP has reached heights that no one expected from this language when it appeared.


But the explosive growth in popularity of PHP has only led to increased demands for increased productivity. Fortunately, the Zend engine has great potential to upgrade.
Although PHP 5 did not become a noticeable step forward and in some cases was even slower than PHP 4, the Zend development team constantly optimized the engine from release to release, as a result PHP 5.6 was 1.5–3 times faster.


But the main breakthrough came with the release of PHP 7 in December 2015. A year later, version 7.1 was announced, which also received a number of improvements.


PHP JIT compiler and expectations for improving PHP 8 performance


A very promising version of Zend is being developed. It will be based on the version from release 7.1, and when it comes out will not be announced yet. So now this is an experimental JIT branch.


One of the main intrigues is related to the Just-In-Time (JIT) compilation. This is a technique for converting code to another format (native machine code) right before execution. The goal of JIT is to increase the speed of the programs. See if developers can keep their promise.


PHP script processing benchmark


For this article, benchmarks were used that measured the performance of script processing on purely processor tasks, that is, without input-output operations: file accesses, connections to a network or database.


The following benchmarks were used:



Benchmarks were chased on the latest minor releases of major PHP versions:



The same benchmarks were run on all intermediate releases, for example, between 5.3.0 and 5.3.29. The results are eloquent: the releases did not show noticeable performance improvements. Improvements were noted only in transitions between major versions, for example, from PHP 5.4 to PHP 5.5 or from PHP 5.6 to PHP 7.


This means that the same scripts will be executed at about the same speed on both PHP 5.4.0 and PHP 5.4.45.


Details on setting up the host system, on the implementation of specific benchmarks and on the interpretation of the results can be read here .


Comparing the results of processor benchmarks


For each benchmark, three values ​​are given:



You can see the results of benchmarking in the table below.


image


(1) The benchmark cannot be executed on versions prior to 5.3, because it uses properties that have not yet been implemented.


(2) The results in this column are a bit biased, because the benchmark needs at least PHP 5.3 to work. They can be taken just for reference, since it cannot be compared with PHP 5.0.


(3) This is a modified version of the mandelbrot.php script that ran too fast in version 7.1.0 in the experimental branch, so it was not possible to measure the speed accurately. Therefore, we did a hundred calculations inside the script, not just one.


Of course, purely processor benchmarks do not allow to evaluate all aspects of PHP performance. Data may not be representative. Nevertheless, based on these data, we can conclude:



Comparison of the performance of different versions of PHP


PHP 5 is much more productive than PHP 4. The Zend engine that underlies the interpreter has been completely redesigned (Zend Engine 2), which paved the way for further improvements. Here we will not cover all the differences between PHP 4 and PHP 5, briefly we will go only through the things implemented after PHP 5.0.


Listed below are the changes that affected the core of PHP. A more detailed list of innovations and changes: PHP 5 and PHP 7 .


PHP 5.1



PHP 5.2



PHP 5.3



PHP 5.4



PHP 5.5



PHP 5.6



PHP 7 vs. PHP 5.6


Most of these improvements relate to the Zend engine:



PHP 7.1 performance improvements



PHP 8 or PHP 7.2 properties, experimental JIT branch



How performance is measured


The benchmark run was a little more complicated than the launch of the Unix time command, and went through several stages:


System Setup


Made a dedicated system with the following characteristics:



Although the system came with a Gnu C 4.7.2 compiler, I had to install a more recent version: the experimental JIT branch should be compiled using Gnu C 4.8 and higher.


Compiling source code


Before building complete distributions, a configure script was run with the following parameters:


 --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 

Of course, I compiled older versions, some parameters needed to be disabled or replaced by others. Also, not all extensions were available or could be compiled.


Run benchmarks


Each benchmark was launched using the PHP CLI (Command-Line Interface) through a special script that did the following:


1) Using the microtime() function on the fly, modified the script to measure its execution time from the inside. After modifying the script looked like this:


 <?php $__start__ = microtime( true ); /***     ***/ fprintf( STDERR, microtime( true ) - $__start__); ?> 

This was done in order to ensure the stability of the dimensions of the script from the inside, without changing its behavior.


2) Then there were two dry runs, so that the executable PHP files and the contents of the benchmark script were in the OS cache.


3) The script was executed five times, the minimum, maximum and average execution times were maintained. This article presents only average values ​​- “script execution time”.


The following settings were used in 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 

Interpretation of results


The duration of execution was measured using the Unix command time . Sample output:


 $ time php bench.php real: 0m1.96s user: 0m1.912s sys: 0m0.044s 

The real value is the time from invoking a command to interrupting it (until it returns to the command line).


The user value is the time spent executing user code (in this case, the executable PHP file).


The sys value is the time spent executing the OS code (kernel). This value should be minimal, but it may turn out to be much larger than the one presented if your code refers, for example, to slow devices. Also, the value of the value is influenced by the high OS load.


On idle systems, the total value of user + sys should be very close to real . In the example above, user + sys = 1,956 , real = 1,960 . The difference of 0.004 s is not connected with our process, but with different OS tasks, for example, with dispatching.


The same script was executed on a highly loaded OS with parallel compiling with three different PHP versions:


 $ time php bench.php real: 0m7.812s user: 0m2.02s sys: 0m0.101s 

As you can see, the level of load greatly affects the execution time (possibly, the system time). Therefore, I added another value to the benchmark - overhead operating system. This is the difference between the total execution time ( elapsed time ) and the sum of user and system time.


I made sure that during the benchmark run this value was less than 100 milliseconds for 99% of the time, even when the execution of scripts took tens of seconds.


Thanks to Dmitry Stogov and the entire PHP development team.


This article was written with the active assistance of Dmitry Stogov. He clarified a number of points and reviewed the information presented here.


image


Dmitry was the developer of the Turck MMCache extension, which since PHP 4 can be used to cache PHP opcodes in shared memory. After that, Dmitry began working on Zend, which he still does.


He also once initiated the creation of PHPNG - what later turned into PHP 7. Nikita Popov and Xinchen Hui collaborated with Dmitry on this and subsequent versions.


Andy Gutmans, Zeev Suraski and Stas Malyshev made a great contribution to the creation of PHP 5. I will not list many other developers here so as not to clutter the article.


Special thank-you video for everyone who helped develop PHP


In 2016, 21 years old since the advent of PHP - June 8, 1995


image


To pay tribute to everyone who somehow contributed to the development of PHP, Peter Kokot with the help of Gource created an animated video. It describes the development of key PHP modules throughout the life of the language.



Peter Kokot is well known in the PHP community. He founded the Facebook PHP Group , the largest group dedicated to a separate programming language. It consists of more than 140 thousand participants and 22 moderators. PHP creator Rasmus Lerdorf said: “In the PHP world, nothing happens without a community movement.” Hope these words will inspire you.


If you can not help the development of PHP by writing C code, you can upload your PHP development on GitHub, PHP Classes, Packagist - anywhere. The more places where we will share with each other developments, the better.


Conclusion


The purpose of this article is to give an idea of ​​the performance of different versions of PHP, starting with 5.0 and ending with the latest experimental version. Testing was performed using well-known benchmarks. The article also contains a list of improvements that improved the performance of various versions of PHP.


')

Source: https://habr.com/ru/post/326696/


All Articles