Table of contents of the article:
In a digital age where speed and efficiency are paramount, website performance can be the difference between business success and failure. In the context of hosting and systems engineering, the search for solutions to optimize performance is incessant. One of the technologies that has attracted great interest among PHP developers is JIT (Just-In-Time) compilation. But what exactly does it imply? And how can it positively influence the performance of your website hosted on a Linux server? Let's find out together.
What is JIT compilation?
JIT, or Just-In-Time, compilation is a compilation method in which source code is translated into machine code at run time, rather than ahead of time. Basically, instead of compiling the source code into an executable format before running it, the code is compiled "on the fly" during its execution.
This approach offers several advantages. For example, it allows the compiler to optimize code based on specific execution conditions, such as hardware platform or operating system. It can also reduce the time it takes to launch an application, since you don't have to wait for all the code to compile before running it.
PHP and JIT
PHP is traditionally known as an interpreted scripting language. This means that the PHP code is executed by an interpreter that reads and processes the source code step-by-step. This approach has its advantages, such as ease of development and portability, but it can also be less efficient than compiling.
With the advent of PHP 8, a revolutionary feature was introduced: JIT compilation. This feature allows PHP to compile parts of the source code into machine code during execution, potentially improving performance.
How does JIT compilation work in PHP?
Purely interpreted programming languages have no compile time and directly run the code in a virtual machine. Most interpreted languages, including PHP, actually have a lightweight compile time to improve its performance.
Programming languages with Ahead-Of-Time (AOT) compilation, on the other hand, require that the code be compiled first and then run.
Just-In-Time compilation is a hybrid model between the interpreter and Ahead-Of-Time compilation, in which some or all of the code is compiled, often at run time, without the developer having to compile it manually.
Historically, PHP was an interpreted language, where all code was interpreted by a virtual machine (Zend VM). This changed with the introduction of Opcache and Opcodes, which were generated from PHP code and could be cached in memory. PHP 7.0 introduced the concept of AST (Abstract Syntax Tree), which further separated the parser from the compiler.
PHP's JIT internally uses DynASM from LuaJIT and is implemented as part of Opcache.
Opcache can inspect used code, commonly called "hot" code, and store compiled versions of it in Opcache's shared memory. When and which code should be compiled is configurable.
Benefits of JIT compiling in PHP
- Improved performance: JIT compilation can lead to dramatic performance improvements, especially for code that executes repeatedly. This can translate into faster loading times and a better user experience.
- Optimization on the fly: Since compilation occurs during execution, the compiler can optimize the code based on specific execution conditions.
- More flexibility: With JIT compilation, developers can take full advantage of the characteristics of the platform on which the code runs, without having to rewrite or re-compile the code.
JIT VS Zend OpCache: what's the difference?
In the PHP ecosystem, performance is a priority. As the language and its extensions have evolved, various solutions have emerged to optimize script execution. Two of the most influential in this context are JIT (Just-In-Time Compilation) and Zend OpCache. But what are their differences and how do they affect PHP performance?
Zend OpCache: Bytecode caching
Zend OpCache is a built-in PHP extension that acts as a bytecode caching system. When a PHP script runs, it goes through several stages: parsing, compiling, and finally running. During the compilation phase, the script is transformed into bytecode, which is an intermediate representation of the source code, optimized for execution.
Zend OpCache intervenes in this process by storing the generated bytecode in a shared memory. This means that for subsequent executions of the same script, PHP can skip the parsing and compiling steps and go directly to executing the stored bytecode. This greatly reduces overhead and speeds up script execution.
If you want to better understand how Zend OpCache works, we have dedicated a specific article: Zend OpCache. How to speed up PHP?
JIT: Compiling at the right time
On the other hand, JIT (Just-In-Time Compilation) is a completely different approach to optimization. Instead of focusing on bytecode caching, JIT compiles PHP code directly to machine code at runtime. This machine code is specifically optimized for the platform it runs on, allowing it to run much faster than interpreted bytecode.
The magic of JIT lies in the fact that it does not compile all the source code, but only the "hot" parts, i.e. those sections of the code that are frequently executed. This makes JIT optimization extremely resource and time efficient.
Comparison and Coexistence
The main difference between Zend OpCache and JIT lies in their approach to optimization:
- Zend OpCache: Focuses on storing bytecode, reducing the overhead associated with parsing and compiling PHP scripts.
- JIT: Focuses on transforming PHP code into optimized machine code, completely bypassing bytecode interpretation.
While these two approaches may seem at odds, they can actually coexist and complement each other. A PHP application can benefit from both the execution speed offered by JIT and the overhead reduction offered by Zend OpCache. In fact, many modern PHP configurations use both extensions to get the best possible performance.
Currently, JIT is enabled on Linux and Windows systems running on x86 and x64 processor instruction sets. Apple M1 and ARM CPUs are not currently supported.
DynASM, which is the underlying assembler used in PHP JIT, also supports ARM instructions, but it is unclear whether PHP JIT can run on ARM processors.
JIT also takes advantage of AVX if supported by the CPU. Most consumer-grade processors and servers from 2011 onwards support AVX instructions.
cat /proc/cpuinfo | grep avx on most POSIX systems you can check if the processor supports it.
Considering the goodness of the solution and of the JIT technology, it is easy to understand that support will probably be extended to many platforms over the next few months and years, however it is always preferable to inquire from your hosting provider.
PHP JIT benchmarks
All of the following tests were performed on an 86-core, 64-thread x8-16 system. The tests, however, never use integers which require 64-bit registers, to keep the test more relevant to x86 CPUs.
The first test was done with Opcache completely disabled and the second with JIT disabled, but opcache enabled.
Both JIT modes bring substantial performance improvements, with
tracingthe slightly more powerful mode.
This benchmark hardly represents a real PHP application. The repetitive calls to the same function and the simpler, side-effect-free nature of the tested code benefit JIT.
A simple function of Fibonacci to calculate the 42nd number in the Fibonacci sequence.
Benchmark web applications with JIT enabled
Evaluating the effect of JIT can be complex, as its impact varies based on the type of workload it is subjected to. Many of the following examples concern concrete web frameworks, but these do not always reflect the typical use in the real context, mainly due to the intervention of various plugins and caching mechanisms.
For applications that connect to a database, the biggest pain point is likely to be database query performance. In a web server simulation where you evaluate requests processed every second, the overheads associated with TLS, HTTP, and FPM could have a far greater impact than the improvements offered by JIT.
Tests were conducted on Laravel (8.4.4) and Symfony (demo 1.6.3, with 5.1.8 components) using their base configurations. These tests were performed on the same hardware and under the same conditions as previous benchmarks. Both frameworks were run through PHP's built-in web server and their performance was evaluated using Apache Bench (ab), with tests done with concurrency of 5 and 100 requests, and the results were obtained from the average of 5 attempts.
Both applications received no noticeable benefit and in Laravel the performance was about 2% worse with JIT, probably due to the compilation overhead that didn't compensate for the efforts.
Analyze and benchmark every single application
To identify actual performance benefits, it is essential to perform a specific benchmark for each application, in order to determine if the adoption of JIT can offer a significant increase in performance.
In particular, CLI applications, especially those that require high CPU usage, may see a dramatic performance boost due to JIT.
On the other hand, for network-oriented or file-intensive applications, such as Composer and PHPUnit, there is likely to be little or no performance benefit.
This is because such applications do not benefit greatly from the machine code-level optimizations offered by JIT. To achieve improvements in these contexts, it may be more effective to invest in larger capacity SSDs, more RAM or higher bandwidth.
PHP hosting with JIT support
Managed Server Srl, always attentive to the latest technological innovations, has recognized the potential of JIT compilation since its announcement. Since the second half of 2020, we have supported JIT for all PHP versions equal to or greater than 8. This commitment reflects our dedication to providing our customers with the most advanced and best-performing solutions available on the market.
If you are considering using JIT PHP for your website, there are a few considerations to keep in mind:
- Compatibility: Make sure your hosting provider, such as Managed Server Srl, supports PHP 8 or later. This is essential to take advantage of JIT compilation.
- Configuration: JIT compilation can be configured in several ways, depending on your needs. Consult the documentation and configure the JIT optimally for your site and server, making sure that your trusted hosting has JIT enabled.
- Performance monitoring: As with any change, it's essential to monitor your site's performance after you enable JIT compilation. This will allow you to identify any problems and further optimize performance.
A New Era for PHP
With the arrival of JIT compilation, PHP is no longer limited to just the web environment. This evolution represents a sea change for language. But what are the real implications of this revolution?
- Extended Application Environments: The ability to leverage JIT compilation opens the door to new horizons for PHP. We are no longer just talking about dynamic web pages, but also desktop applications, embedded systems, and even artificial intelligence or data analysis applications. PHP could find its way into contexts where, until now, it was unthinkable.
- Resource Optimization: JIT compilation takes full advantage of the resources provided by modern processors. This means that PHP applications will be able to perform complex operations much more efficiently, making the most of the available computing power.
- High Performance: In scenarios where speed and efficiency are critical, such as real-time analytics applications or high-performance computing systems, PHP with JIT can offer performance comparable to traditionally faster languages.
JIT compilation represents a significant evolution for PHP, offering the potential to dramatically improve the performance of web applications. For Linux hosting and systems engineering companies, such as Managed Server Srl, which offer high-performance hosting solutions, it is essential to stay updated on the latest technologies and offer customers the best possible solutions. JIT compiling in PHP is just one of the tools available to achieve this. Make sure you make the most of it!