This project aims to compare the performance of some most used and few less known JSON serialization libraries for PHP.
- JMS Serializer
- Symfony Serializer
- TSantos Serializer
- Zumba Json Serializer
- Nil Portugués
- Gson
- Better Serializer
This benchmark attempts to compare serialization libraries performance-wise. All of the libraries have their own features, support different formats, added magic and other stuff, but for the sake of simplicity it was decided to simplify sample data to fit all of them.
The core of benchmarking set was implemented by Tales Santos, the author of TSantos serializer.
git clone https://github.com/tsantos84/serializers-benchmarking.gitUsing system installed composer
composer install -a --no-devor using composer in docker container:
docker run --rm --interactive --tty -v $(pwd):/app composer install -a --no-devThe benchmark application can be executed as is with PHP 7.1 and above.
php vendor/bin/phpbench run --warmup=1 --report=tsantosIf you don't have PHP of required version you may use suitable Docker PHP image (PHP 7.1-cli-alpine).
docker run --rm -it -v $(pwd):/opt -w /opt php:7.1-cli-alpine php vendor/bin/phpbench run --warmup=1 --report=tsantos --group=serializeThere're 2 available benchmark groups:
serialize- run serialization benchmark onlydeserialize- run deserialization benchmark only
php vendor/bin/phpbench run --warmup=1 --report=tsantos --group=serializeIt is possible to see all the serializer libraries available in this benchmark and its version:
php vendor/bin/phpbench vendorsThis project was written based on PHPBench. Please, refer to its documentation page for further reading about all its runner options.
Blackfire is a excelent tool to profile PHP applications and helps you to discover some bottleneck points. This project allows you to run benchmarks and send the call-graph to Blackfire's server so you can see how each library works internally.
In order to start using Blackfire, you first need to sign up on Blackfire.io and then you'll have access to your credentials.
Creates a new docker container with the Blackfire's Agent:
docker run -d \
--name="blackfire" \
-e BLACKFIRE_SERVER_ID={YOUR_BLACKFIRE_SERVER_ID_HERE} \
-e BLACKFIRE_SERVER_TOKEN={YOUR_BLACKFIRE_SERVER_TOKEN_HERE} \
blackfire/blackfireCreate a custom PHP image with Blackfire extension installed and enabled:
cd /path/to/serializer-benchmark
docker build -t benchmark -f Dockerfile.blackfire .Now you can run the application using the PHP image create on step before:
docker run \
--rm \
-it \
-v $(pwd):/opt \
-w /opt \
-e BLACKFIRE_CLIENT_ID={YOUR_BLACKFIRE_CLIENT_ID_HERE} \
-e BLACKFIRE_CLIENT_TOKEN={YOUR_BLACKFIRE_CLIENT_TOKEN_HERE} \
--link blackfire:blackfire \
benchmark php vendor/bin/phpbench run --warmup=1 --report=tsantos --group=serialize --executor=blackfireInstead of running each container manually, you can use docker-compose to run the benchmarks. To accomplish this
you need to create a copy of the docker-compose.yaml.dist file:
cp docker-compose.yml.dist docker-compose.ymland run one of the following commands:
# perform serialization benchmark
docker-compose run --rm bench_serialize
# perform deserialization benchmark
docker-compose run --rm bench_deserialize
# perform serialization benchmark with Blackfire enabled
docker-compose run --rm bench_serialize_blackfire \
-e BLACKFIRE_SERVER_ID={YOUR_BLACKFIRE_SERVER_ID} \
-e BLACKFIRE_SERVER_TOKEN={YOUR_BLACKFIRE_SERVER_TOKEN} \
-e BLACKFIRE_CLIENT_ID={YOUR_BLACKFIRE_CLIENT_ID} \
-e BLACKFIRE_CLIENT_TOKEN={YOU_BLACKFIRE_CLIENT_TOKEN}
# perform deserialization benchmark with Blackfire enabled
docker-compose run --rm bench_deserialize_blackfire \
-e BLACKFIRE_SERVER_ID={YOUR_BLACKFIRE_SERVER_ID} \
-e BLACKFIRE_SERVER_TOKEN={YOUR_BLACKFIRE_SERVER_TOKEN} \
-e BLACKFIRE_CLIENT_ID={YOUR_BLACKFIRE_CLIENT_ID} \
-e BLACKFIRE_CLIENT_TOKEN={YOU_BLACKFIRE_CLIENT_TOKEN}As you have your own copy of the docker-compose.yml file, you can define those environment variables there
and save time when run the benchmarks with Blackfire enabled.
By running the benchmark with Blackfire enabled you'll realize that the mean time will increase substantially. This behavior is expected because the Blackfire needs to introspect in your code and hence affects the benchmark metrics.
Want to see more libraries in this benchmark? You can easily add new benchmarks by implementing the BenchInterface interface or extending the AbstractBench class which has a lot of help methods. Please, take a look at some of existing bench classes and you'll see how you can write your own benchmark.