PECL's Yaml Way Faster Than Symfony's Yaml

· klm's blog


Original post is here: eklausmeier.goip.de

PECL is the PHP Extension Community Library. These extensions are written in C. Symfony is a PHP web application framework written in PHP.

Initially I just wanted to reduce the dependencies in Saaze, so I installed PECL PHP package yaml. When I compared run-times between the original, "old" Symfony-based Yaml parsing and the new C based Yaml parsing, I noticed that run-time went down from 1.3s to 0.9s. I then found out that more than 40% of the run-time in Saaze is Yaml parsing.

PHP documents an official Yaml parser: yaml_parse. Saaze instead uses the Symfony supplied Yaml parser.

1. Installation. Here are the steps to install the yaml PECL from source. Arch Linux and Ubuntu provide precompiled packages. In that case there is no need to go through below steps.

  1. Download latest yaml package from PECL
  2. tar zxf yaml...
  3. Run phpize
  4. Run ./configure
  5. Run make. Library is here modules/yaml.so.
  6. Run make test. Conducted 74 tests, which all succeeded.
  7. As root copy modules/yaml.so to /usr/lib/php/modules
  8. Edit /etc/php/php.ini and add extension=yaml

Now you should see a yaml entry when calling phpinfo() or php -m or php -i.

2. Code changes. I changed function parseEntry() in Entry.php and added time measurements:

1$t0 = microtime(true);
2. . .
3$GLOBALS['YamlParser'] += microtime(true) - $t0;

The original call $matter = Yaml::parse($matter); is changed to $matter = yaml_parse($matter);. Below dependency is no longer required:

1use Symfony\Component\Yaml\Yaml;

3. Performance comparison. Old run-times:

 1$ time php saaze build
 2Building static site in /home/klm/tmp/sndsaaze/build...
 3        execute(): filePath=/home/klm/tmp/sndsaaze/content/blog.yml, entries=1, totalPages=11, entries_per_page=30
 4        execute(): filePath=/home/klm/tmp/sndsaaze/content/music.yml, entries=1, totalPages=1, entries_per_page=30
 5        execute(): filePath=/home/klm/tmp/sndsaaze/content/pages.yml, entries=1, totalPages=1, entries_per_page=30
 6Finished creating 3 collections and 338 entries (1.25 secs / 10.17MB), YamlParser=0.48152208328247, md2html=0.21977066993713, MathParser=0.10401964187622
 7        real 1.31s
 8        user 1.15s
 9        sys 0
10        swapped 0
11        total space 0

New run-times:

 1$ time php saaze build
 2Building static site in /home/klm/tmp/sndsaaze/build...
 3        execute(): filePath=/home/klm/tmp/sndsaaze/content/blog.yml, entries=1, totalPages=11, entries_per_page=30
 4        execute(): filePath=/home/klm/tmp/sndsaaze/content/music.yml, entries=1, totalPages=1, entries_per_page=30
 5        execute(): filePath=/home/klm/tmp/sndsaaze/content/pages.yml, entries=1, totalPages=1, entries_per_page=30
 6Finished creating 3 collections and 338 entries (0.88 secs / 10.16MB), YamlParser=0.11651396751404, md2html=0.22396731376648, MathParser=0.10581231117249
 7        real 0.94s
 8        user 0.77s
 9        sys 0
10        swapped 0
11        total space 0

Above numbers for the old run-times show a ratio of 0.48/1.25, i.e., roughly 40% of the old run-time is Yaml parsing. For the new version the ratio is 0.12/0.88, i.e., roughly 13%.

4. Caveats. Whenever a new PHP version comes out, you have to re-install the extension. For example, from PHP 8.0 to 8.1 you have to recompile and re-install. Check as below:

1$ php -v
2PHP Warning:  PHP Startup: yaml: Unable to initialize module
3Module compiled with module API=20200930
4PHP    compiled with module API=20210902
5These options need to match
6 in Unknown on line 0
7PHP 8.1.2 (cli) (built: Jan 21 2022 18:08:47) (NTS)
8Copyright (c) The PHP Group
9Zend Engine v4.1.2, Copyright (c) Zend Technologies

Added 14-Jan-2023: Installing PECL yaml package is easy on Arch Linux, because there is an AUR package php-yaml. In case of a PHP version update you remove php-yaml with pacman -R, then reinstall again with your favorite AUR helper. One particular good AUR helper is trizen.

Added 17-Jan-2023: Installing PECL yaml package is also easy on Ubuntu. Just run apt-get install php-yaml.

Added 15-Jan-2024: Reinstalling on Arch Linux is like this:

1trizen -au php-yaml