PHP 8 introduces two JIT compilation engines. Tracing JIT, the most promising of the two, shows about 3 times better performance on synthetic benchmarks and 1.5–2 times improvement on some specific long-running applications. Typical application performance is on par with PHP 7.4. Relative JIT contribution to PHP 8 performance. Most exciting with PHP 8.0 is the JIT compiler that has the ability to provide better performance on top of all the gains already scored during PHP 7.x releases. PHP 8.0 is also bringing support for static return types, weak maps, union types, improved errors and warnings, and more is surely to come - stay tuned to the PHP RFC page. PHP 8: JIT performance in real-life web applications For those interested in the JIT in PHP 8, I did some benchmarks for you in real-world web application scenario. Be aware that these benchmarks don't say anything about whether the JIT is useful or not, they only show whether it can improve the performance of your average web application, or not.
This entry was posted in WordPress Security on November 23, 2020 by Ram Gall18 Replies
Php 8 Performance Data
PHP 8.0 is set to be released on November 26, 2020. As the programming language powering WordPress sites, PHP’s latest version offers new features that developers will find useful and improvements that promise to greatly enhance security and performance in the long run. It also fully removes a number of previously deprecated functions. PHP 8 is a massive change from previous versions.
In this article, we hope to provide insights detailing what this means for WordPress site owners, including recommended adoption strategies.
Should I upgrade right away?
No. The upcoming major version of WordPress, 5.6, is intended to be “beta compatible with PHP 8” according to the November 18 WordPress dev chat. This means that most core WordPress functionality will work, but unexpected bugs may still occur for some time, even without the presence of additional plugins or themes. WordPress has called for additional testing with PHP 8 in order to find and fix as many remaining bugs as possible.
At Wordfence, our Quality Assurance team is working to ensure that our plugin is compatible with PHP 8 in a variety of environments. Upcoming Wordfence versions will offer a similar level of partial support, though we have additional testing planned to reach full compatibility.
A vast number of WordPress plugins and themes will not be immediately compatible with PHP 8. Those that do not run into fatal errors during normal usage may still show unexpected behavior for some time.
What breaking changes does this include?
Some developers have long argued that PHP is insecure by default. While this is up for debate, it’s true that versions of PHP prior to PHP 8 are more fault tolerant and try very hard to ensure that code will run even if minor errors are present.
PHP 8 uses much stricter typing than previous versions. Many built-in functions are now pickier about the input they accept, and PHP 8 itself is more stringent about how input is passed to functions. Issues that previously resulted in notices now result in warnings, and issues that previously resulted in warnings now result in errors.
In other words, PHP 8 is not as lenient as previous versions. It will not try quite as hard to make code work no matter what.
Some functions and features that were deprecated in PHP 7.x have been completely removed. These include:
- The
$php_errormsg
variable - The
create_function()
function - The
mbstring.func_overload
ini directive - The
real
type - The
allow_url_include
ini directive - The
restore_include_path()
function - The
each()
function
While most of these are no longer widely used, we have identified that
create_function
is still used in over 5,500 WordPress plugins, including extremely popular plugins with millions of installations. In some cases use of these deprecated functions may be intended for backwards compatibility with older versions of PHP. Many plugins, however, will need extensive refactoring as PHP 8 becomes more utilized.Quite a few plugins and themes also depend heavily on third party libraries. WordPress developers may need to wait until these are updated for compatibility. If these libraries are not maintained or updated for compatibility with PHP 8, it may be necessary to fork these libraries, find alternatives, or even rewrite plugins and themes from the ground up.
For more in-depth information about what’s changed, our friends at Yoast have produced an excellent compatibility report intended for developers looking to ensure their software is compatible.
What security concerns are there?
PHP allows something called “Type Juggling.” This means that it can treat strings containing numbers the same way it treats integers or floats, and can perform math and do comparisons between these different types as long as the loose comparison operator is used instead of the strict comparison operator . For developers, Type Juggling can be very useful and save time when writing code, but it can sometimes lead to unusual behavior.
A classic example of how Type Juggling can cause issues is that comparing
0”blah”
will return true
. PHP 8 fixes this type of behavior so that these and similar comparisons (e.g., 0”0blah”
) will return false
.By and large, this will actually improve security. There are a number of exploits that can take advantage of PHP’s Type Juggling behavior to bypass nonstandard cookie, nonce, or password checks. Nonetheless, a large number of plugins use these loose comparisons, sometimes for critical functions. In most cases these will continue to work correctly when using PHP 8, but a few of them might actually rely on incorrect behavior in order to function properly. In a few rare circumstances, this might open up new security holes.
The onus of updating code for compatibility with PHP 8 could prove to be too much for some developers, and many plugins and themes may end up abandoned, though this is less likely to happen for plugins and themes with a large install base. Any security issues in these abandoned plugins and themes would go unpatched, which could prove disastrous.
Likewise, many websites may remain on an insecure version of PHP in order to keep their legacy plugins running.
Finally, certain strains of malware rely on deprecated functions as well as PHP’s fault tolerance in order to obfuscate their intentions. These strains will cease to function or become more noticeable in a PHP 8 environment, but malware authors will adapt in time.
What performance changes are coming?
One potentially exciting feature coming to PHP 8 is JIT, or “Just In Time” compilation. PHP is an interpreted language, meaning that it is translated into machine code as it runs. JIT keeps track of code that’s frequently used and attempts to optimize the machine code translation so that it can be reused. This can result in a massive performance improvement for specific functionality.
The addition of JIT to other languages, such as JavaScript, has historically led to an explosion of new applications. For example, virtual machines running in JavaScript would have been unimaginable in the early days of the web. Certain tasks that would have required a module to be installed on the server in the past will become practical using pure PHP libraries.
For the time being, however, the actual performance improvement for web applications such as WordPress is minimal, and it will take a long time before the average WordPress user or developer reaps the benefits of this new feature.
While there are many other new features to make developers’ lives easier, it is unlikely that these will be used in WordPress plugins and themes for the foreseeable future, as most would break backwards compatibility with earlier versions of PHP still in use by many WordPress sites.
How long do developers have to update?
Each version of PHP has a life cycle of 2 years during which bugs are fixed, and an additional year during which security issues are patched. PHP 7.4 came out in November 2019. As the final version of PHP 7, this means that bugs in PHP 7.4 will be fixed until November of 2021, and security issues will be patched until November of 2022, at which point it will reach its “End of Life”. This means that November 2022 can be considered a hard cutoff date: all PHP code should be compatible with PHP 8.0 at minimum by this time, or risk being stuck on a potentially vulnerable version of PHP.
Conclusion
The transition to PHP 8 is one of the broadest and most impactful changes the language has ever seen. While it will be worth it in the long run, WordPress site owners and developers may be in for a rough ride in the short term. If you’re a website owner, start keeping a watchful eye on which of your plugins and themes are being updated or tested for compatibility and make a plan to replace the ones that aren’t. If you’re a developer, start testing your code and any dependencies on PHP 8, if you’re not already, and start making a plan to fork or replace any libraries that aren’t being updated. The WordPress ecosystem has been through difficult transitions in the past, and our open-source community has always grown and adapted.
Special thanks to QA Lead Matt Rusnak and Lead Developer Matt Barry for their assistance with this article.
« back — written by Brent on July 02, 2020 For those interested in the JIT in PHP 8, I did some benchmarks for you in real-world web application scenario. Be aware that these benchmarks don't say anything about whether the JIT is useful or not, they only show whether it can improve the performance of your average web application, or not.
# Setup
Let's set the scene first. These benchmarks were run on my local machine. As so, they don't say anything about absolute performance gains, I'm only interested in making conclusions about the relative impact the JIT has on real-life code.
I'll be running PHP FPM, configured to spawn 20 child processes, and I'll always make sure to only run 20 concurrent requests at once, just to eliminate any extra performance hits on the FPM level. Sending these requests is done using the following command, with ApacheBench:
# JIT Setup
With the project in place, let's configure the JIT itself. The JIT is enabled by specifying the
opcache.jit_buffer_size
option in php.ini
. If this directive is excluded, the default value is set to 0, and the JIT won't run.You'll also want to set a JIT mode, which will determine how the JIT will monitor and react to hot parts of your code. You'll need to use the
opcache.jit
option. Its default is set to tracing
, but you can override it using function
:In our real-life benchmarks, I'll compare both modes with each other.So let's start benchmarking!
# Establishing a baseline
First it's best to establish whether the JIT is working properly or not. We know from the RFC that it does have a significant impact on calculating a fractal. So let's start with that example. I copied the mandelbrot example from the RFC, and accessed it via the same HTTP application I'll run the next benchmarks on:
Crusader kings iii best price pc. Crusader Kings III is the heir to a long legacy of historical grand strategy experiences and arrives with a host of new ways to ensure the success of your royal house. Recent Reviews: Very Positive (1,117) - 91% of the 1,117 user reviews in the last 30 days are positive.
Jura wine region map. After running
ab
for a few hundred requests, we can see the results:requests/second (more is better) | |
Mandelbrot without JIT | 3.60 |
Mandelbrot with tracing JIT | 41.36 |
Great, it looks like the JIT is working! That's even a ten times performance increase! Having verified it works as expected, let's move on to our first real-life comparison. We're going to compare no JIT with the function and tracing JIT; using 100MB of memory. The page we're going to benchmark shows an overview of posts, so there's some recursion happening. We're also touching several core parts of Laravel as well: routing, the dependency container, as well as the ORM layer.
Side note:
Php 8 Jit Performance Benchmark
If you want to verify whether the JIT is running, you can use
opcache_get_status()
, it has a jit
entry which lists all relevant information:requests/second (more is better) | |
No JIT | 63.56 |
Function JIT | 66.32 |
tracing JIT | 69.45 |
Here we see the results: enabling the JIT only has a slight improvement. In fact, running the benchmarks over and over, the results differ slightly every time: I've even seen cases where a JIT enabled run performs worse than the non JIT'ed version. Before drawing final conclusions, let's bump the memory buffer limit. We'll give the JIT a little more room to breathe with 500MB of memory instead of 100MB.
requests/second (more is better) | |
No JIT | 71.69 |
Function JIT | 72.82 |
Tracing JIT | 70.11 |
As you can see: a case of the JIT performing worse. Like I said at the beginning of this post: I want to measure the relative impact the JIT has on real-life web projects. It's clear from these tests that sometimes there might be benefits, but it's in no way as noticeable as the fractal example we started out with. I admit I'm not really surprised by that. Like I wrote before: there's very little hot code to be optimised in real-life applications, we're only rarely doing fractal-like computations.
Target_link_libraries. So am I saying there's no need for the JIT? Not quite, I think the JIT can open up new areas for PHP: areas where complex computations do benefit from JIT'ed code. I'm thinking about machine learning, AI, stuff like that. The JIT might give opportunities to the PHP community that didn't exist yet, but it's unclear to say anything with certainty at this point.
So, that concludes my JIT testing. As expected: the JIT probably won't have a significant impact on web applications, at least not right now.
I won't discuss my thoughts on whether the JIT itself is a good addition or not in this post, let's have those discussions together over here!