PHP
PHP’s suite rows cover stdlib JSON, native serialize, optional PECL binaries (igbinary, MessagePack, LibYAML, SIMDJSON, MongoDB BSON), official google/protobuf, Symfony and JMS JSON (plus Symfony XML), Avro, CBOR, and pure-PHP MessagePack / YAML as userland baselines.
Runtime
What it is
PHP is often described as a language for web pages. This suite runs the CLI (command-line) binary, not PHP-FPM or Apache. The engine is Zend. It compiles a script to opcodes, which are an intermediate instruction set, and then executes those opcodes. The short, request-scoped life cycle of a web page does not apply here. One process runs many timed repetitions.
| This suite | |
|---|---|
| Language | PHP 8.2 or newer (composer.json). The install script offers a static 8.3 CLI. |
| Packages | Composer (composer install) |
| Prepare | ./scripts/install-host-requirements.sh php installs into ~/.local/php |
| Run | php/scripts/run-benchmarks.sh |
| Memory | Zend allocator, plus a garbage collector for cyclic structures |
What this suite runs
The install script’s static CLI is built without PECL extensions. PECL is the usual way to add C extensions such as igbinary, msgpack, yaml, simdjson, and mongodb to PHP. Those rows register only when the matching extension is actually loaded. A missing row on the Dashboard often means this PHP binary was built without that extension. It does not mean the library is slow.
What changes the numbers
PECL and other C extensions are typically much faster than pure-PHP packages such as rybakit/msgpack and symfony/yaml. google/protobuf reports +ext or +php in the version column, depending on which implementation loaded. The built-in serialize format works only in PHP.
Suite-specific gotchas
A host that has the PECL rows and a host that does not are not the same matrix. Compare them only after you know which extensions were loaded.
These times cannot be ranked against another language.
Where to go next
The steps to install the toolchain and run the benchmark are in php/README.md. The language overview is What is PHP?.
Benchmark runner
- Directory:
php/(repository root) - Output:
logs/php/YYYY-MM-DD-HHMMSS.csv(Language=php, times in nanoseconds) - Runner:
php/scripts/run-benchmarks.sh {smoke|all-single|full|research} - Registration:
php/src/Serializers/Registry.php - Protobuf classes:
php/scripts/generate-protobuf.sh(fromschemas/v2/protobuf/benchmark_v2.proto)
PECL rows register only when the extension is loaded. This host’s static PHP CLI has none of those extensions, so those rows stay dark until igbinary / msgpack / yaml / simdjson / mongodb are present.
Serializers
| Name | Category | Package | Stream | Notes |
|---|---|---|---|---|
| json | JSON | php-json | text_on_stream | json_encode / json_decode |
| simdjson | JSON | ext-simdjson | text_on_stream | Decode only is SIMDJSON; encode is json_encode |
| serialize | Binary | php-serialize | adapted | PHP-only |
| igbinary | Binary | ext-igbinary | adapted | PECL; skip if missing |
| msgpack-pecl | Binary | ext-msgpack | adapted | PECL; skip if missing |
| rybakit-msgpack | Binary | rybakit/msgpack | adapted | Pure PHP MessagePack |
| protobuf | Schema | google/protobuf | adapted | Official generated messages; +ext vs +php in version |
| symfony-json | JSON | symfony/serializer | text_on_stream | Serializer JSON encoder |
| symfony-xml | Text | symfony/serializer | text_on_stream | Serializer XML encoder |
| jms-json | JSON | jms/serializer | text_on_stream | JMS JSON |
| bson | Binary | ext-mongodb | adapted | Official BSON; skip if missing |
| avro | Schema | flix-tech/avro-php | adapted | Binary Avro (no object container) |
| cbor | Binary | spomky-labs/cbor-php | adapted | RFC 8949 |
| yaml | Text | symfony/yaml | text_on_stream | Pure PHP YAML |
| yaml-pecl | Text | ext-yaml | text_on_stream | LibYAML; skip if missing |
| gld-arrow | Schema | leo-gan/gld-arrow-php 0.2.0 | adapted | Arrow IPC stream for the five suite types |
| gld-ion | Binary | leo-gan/gld-ion-php 0.2.0 | adapted | Ion 1.0 binary encode / decode |
Specifics
Why each library exists, what problem it was written to solve, and how. Names link to the source repository (or the stdlib / in-tree path this suite times). A version after the name is the last measured SerializerVersion from this suite's latest bench.
json · 8.3.19
PHP's json_encode / json_decode are the language's standard JSON APIs. They exist so PHP can speak the web's data format without a package. This row times the bundled ext-json.
simdjson
ext-simdjson binds the simdjson parser to PHP. simdjson was created to parse JSON at memory-bandwidth speeds. This row uses SIMD only for decode; encode is json_encode.
serialize · 8.3.19
PHP serialize / unserialize is the language's native object format. It exists so PHP can persist values across requests. It is PHP-only and unsafe for untrusted input.
igbinary
igbinary is a PECL replacement for PHP serialize with a more compact binary. The problem was PHP's verbose native serializer in caches and sessions. igbinary drops duplicate strings and uses a denser layout.
msgpack-pecl
ext-msgpack is the official PECL MessagePack extension for PHP. MessagePack exists as compact binary JSON. The C extension is the fast path versus userland MessagePack.
rybakit-msgpack · v0.9.2
rybakit/msgpack is a pure-PHP MessagePack implementation. MessagePack exists as compact binary JSON. This package is the userland baseline versus the PECL extension.
protobuf · v4.33.6+php
Protocol Buffers were created at Google so many languages could share a compact, evolving binary contract without hand-written parsers. The problem was ad-hoc binary formats and verbose XML. Protobuf solves it with an IDL, generated code, and a documented tag/length wire format.
symfony-json · v7.4.18
The Symfony Serializer component was created so Symfony apps had a normalizer/encoder pipeline for JSON, XML, and more. The problem was ad-hoc json_encode of domain objects. This suite times the JSON and XML encoders.
symfony-xml · v7.4.18
The Symfony Serializer component was created so Symfony apps had a normalizer/encoder pipeline for JSON, XML, and more. The problem was ad-hoc json_encode of domain objects. This suite times the JSON and XML encoders.
jms-json · 3.32.9
JMS Serializer was created for PHP applications that needed annotation-driven object serialization (especially APIs). The problem was mapping rich object graphs to JSON. This row times the JSON encoder.
bson
BSON (Binary JSON) was created for MongoDB so documents could be stored and traversed without a text parse. Official language drivers implement that spec. This row times that library's serialize/deserialize path.
avro · 5.2.0
flix-tech/avro-php is a PHP implementation of Apache Avro. Avro exists for compact, schema-driven records. This row times binary Avro (not the object container file format).
cbor · 3.4.1
spomky-labs/cbor-php implements RFC 8949 CBOR in PHP. CBOR is the IETF binary JSON-like format. The library is a PHP encoder/decoder of that RFC.
yaml · v7.4.18
The Symfony YAML component is a pure-PHP YAML parser/dumper. YAML exists as a human-friendly config language. Symfony YAML is the common userland implementation in PHP apps.
yaml-pecl
ext-yaml is the PECL binding to LibYAML. YAML exists as a human-friendly config language. The extension is the C-speed path versus Symfony's pure-PHP YAML.
gld-arrow · 0.2.0
gld-arrow-php is a from-scratch Apache Arrow library for PHP. This row writes one IPC stream for a suite value or a batch and reads it back. It is not the columnar data set.
gld-ion · 0.2.0
gld-ion-php is a from-scratch Amazon Ion library for PHP. Ion exists as a typed superset of JSON with a binary encoding. This row times Ion 1.0 binary encode and decode on the five suite types.
Not in this suite (and why)
These candidates from the intake lists are not rows:
| Candidate | Why not |
|---|---|
| Goridge / RoadRunner | RPC framing, not a fixture codec |
| opis/closure, laravel/serializable-closure | Packs executable closures — not suite data, and a security surface |
| salsify/jsonstreamingparser | Decode-only SAX parser |
| clue/ndjson | Line-delimited stream, different payload |
| Symfony CSV | Nested fixtures are not a CSV table |
| Spatie laravel-data / Laravel serialization | Framework hydrators, not a wire format |
| YAS PHP / AMQP codecs | No official PHP codec for this suite’s fixtures |
| Cap’n Proto PHP | No official PHP runtime |
| FlatBuffers / Thrift PHP | No generated PHP tables in-tree yet (can be added like protobuf) |
| PDO / custom hydrators | Object mapping, not encode/decode of bytes |