PHP Performance in 2022: A Year in Review

Now that 2022 is over, its time to review newsworthy topics about performance in the PHP language.

As this is the first time we are doing this type of blog post, please let us know your thoughts about this format and if we forgot important topics.

PHP 8.2 release 

With each new release of PHP, there are performance improvements to the engine or individual parts of the language. A list of performance related changes in the PHP 8.2.0 release from this year includes the following topics, discussed in more detail below:

  • Packed Arrays (List Arrays) are stored in a more efficient data structure, leading to reduced memory footprint and better performance.
  • stripos() performance improved significantly
  • Performance of different functions in mbstring extension improved
  • new memory_reset_peak_usage() function introduced

Tideways also already supports PHP 8.2 and a handful of customers are already running it in production.

More efficient packed arrays (lists)

Arrays in PHP are lists, hashmaps or both at the same time. For the “array as list with items indexed by 0” use case, PHP 8.2 ships with a more memory-efficient representation, contributed by Dmitry Stogov in #7491

This change significantly reduces the memory overhead of the array structure.

A test script that creates an array list of integers with 100 items reduces memory usage from 4,3 MB to 2,3 MB (3v4l.org):

<?php

function build_list() {
    $list = [];

    for ($i = 0; $i < 100000; $i++) {
        $list[] = $i;
    }
}

var_dump(memory_get_peak_usage() / 1024 / 1024);

stripos() performance improved

Before PHP 8.2, stripos would lowercase the string and then use strips internally, which has suboptimal performance semantics for a few edge cases.

In PHP 8.2 Ilija Tovilo added a custom stripos implementation in PR #7852 that exhibits better performance characteristics for all use-cases.

Performance of different functions in mbstring extension improved

Alex Dowad is consistently working on improving the mbstring extension and PHP 8.2 includes a large range of PRs that increase the performance of different functions in mbstring for different character sets.

New memory_reset_peak_usage() function introduced

With the new function memory_reset_peak_usage() contributed to PHP 8.2 by Patrick Allaert in #8151, the value for the memory_get_peak_usage() resets to the currently used memory. This function is helpful for PHP scripts that perform multiple tasks, such as daemons, workers and cronjobs, to accurately measure each task’s peak memory impact.

Franken PHP

A new experimental web server for PHP was released called FrankenPHP. It is written in Go and uses the Embed SAPI to run PHP requests as threads within the Go web server.  

The interaction between Go and PHP is possible with a recent 8.2 version and higher, It also requires  PHP to be compiled with ZTS (Zend Thread Safety). 

FrankenPHP is an interesting project to watch because it is the first time a „SAPI“ directly includes a powerful web server (based on Caddy). This could simplify deployment of PHP applications compared to running both Nginx/Apache and PHP-FPM.

FrankenPHP is also the only PHP SAPI that provides HTTP 103 Early Hint support to increase performance for certain sites.

Revolt Event Loop released stable version

With PHP 8.1 Fibers were introduced to allow cooperative multi-tasking. Now in 2022, the first projects are now building on Fibers to provide new frameworks and features to PHP users.

The revolt/event-loop  is a Composer package that provides the basic building blocks for a Fiber-based event loop. It released the first stable version 1.0 in November 2022.

React-PHP and amphp are currently integrating Revolt in their event loop implementations.

Did we miss anything important? Let us know [email protected] or @tideways on Twitter.

Photo by Jason Leung on Unsplash

Benjamin Benjamin 04.01.2023