, 3 min read
PECL's Yaml Way Faster Than Symfony's Yaml
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.
- Download latest yaml package from PECL
tar zxf yaml...
- Run
phpize
- Run
./configure
- Run
make
. Library is heremodules/yaml.so
. - Run
make test
. Conducted 74 tests, which all succeeded. - As root copy
modules/yaml.so
to/usr/lib/php/modules
- Edit
/etc/php/php.ini
and addextension=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:
$t0 = microtime(true);
. . .
$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:
use Symfony\Component\Yaml\Yaml;
3. Performance comparison. Old run-times:
$ time php saaze build
Building static site in /home/klm/tmp/sndsaaze/build...
execute(): filePath=/home/klm/tmp/sndsaaze/content/blog.yml, entries=1, totalPages=11, entries_per_page=30
execute(): filePath=/home/klm/tmp/sndsaaze/content/music.yml, entries=1, totalPages=1, entries_per_page=30
execute(): filePath=/home/klm/tmp/sndsaaze/content/pages.yml, entries=1, totalPages=1, entries_per_page=30
Finished creating 3 collections and 338 entries (1.25 secs / 10.17MB), YamlParser=0.48152208328247, md2html=0.21977066993713, MathParser=0.10401964187622
real 1.31s
user 1.15s
sys 0
swapped 0
total space 0
New run-times:
$ time php saaze build
Building static site in /home/klm/tmp/sndsaaze/build...
execute(): filePath=/home/klm/tmp/sndsaaze/content/blog.yml, entries=1, totalPages=11, entries_per_page=30
execute(): filePath=/home/klm/tmp/sndsaaze/content/music.yml, entries=1, totalPages=1, entries_per_page=30
execute(): filePath=/home/klm/tmp/sndsaaze/content/pages.yml, entries=1, totalPages=1, entries_per_page=30
Finished creating 3 collections and 338 entries (0.88 secs / 10.16MB), YamlParser=0.11651396751404, md2html=0.22396731376648, MathParser=0.10581231117249
real 0.94s
user 0.77s
sys 0
swapped 0
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:
$ php -v
PHP Warning: PHP Startup: yaml: Unable to initialize module
Module compiled with module API=20200930
PHP compiled with module API=20210902
These options need to match
in Unknown on line 0
PHP 8.1.2 (cli) (built: Jan 21 2022 18:08:47) (NTS)
Copyright (c) The PHP Group
Zend 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:
trizen -au php-yaml