fastjson 0.4.0 benchmark baseline

A PHP extension that wraps yyjson 0.12.0 behind a fastjson_* API mirroring ext/json. Side-by-side throughput, memory, and per-call latency against stock ext/json on a 21-file corpus, both hosted by PHP 8.4.22-dev.

Hardware: 13th Gen Intel(R) Core(TM) i9-13950HX Build: release, both PHP and extension -O2 Iterations: 300 per case, slowest 10% dropped Corpus: 21 files — 15 large (14.81 MB) + 6 small (64.6 KB), from simdjson_php's jsonexamples

2.59x

Decode

vs ext/json, decode → stdClass (14.81 MB large corpus aggregate).

5.92x

Encode

vs ext/json, encode a PHP value to JSON (14.81 MB large corpus aggregate).

5.23x

Validate

vs ext/json, validate without building a tree (14.81 MB large corpus aggregate).

Decode PHP 8.4.22-dev

Decode to stdClass. fastjson's decode path is unchanged from yyjson's reader; assoc-array decode tracks it closely (see bench/baseline.md for the full assoc table).

ext/jsonPHP 8.4.22-dev
209 MB/s
fastjson 0.4.0PHP 8.4.22-dev
542 MB/s
05001,000 MB/s
Aggregate on the 14.81 MB large corpus. fastjson is 2.59x ext/json.

Per-file decode, large corpus

FileSize ext/jsonMB/s fastjsonMB/s fastjson vsext/json
apache_builds.json124.3 KB 367 980 2.67x
canada.json2.15 MB 95 386 4.07x
citm_catalog.json1.65 MB 446 1,065 2.39x
github_events.json63.6 KB 413 1,260 3.05x
gsoc-2018.json3.17 MB 335 1,044 3.11x
instruments.json215.2 KB 345 918 2.66x
marine_ik.json2.85 MB 180 297 1.65x
mesh.json706.6 KB 188 483 2.57x
mesh.pretty.json1.50 MB 242 654 2.70x
numbers.json146.6 KB 225 919 4.09x
random.json498.5 KB 246 465 1.89x
stringifiedphp.json139.9 KB 338 2,487 7.36x
twitter.json616.7 KB 393 942 2.40x
twitterescaped.json549.2 KB 296 779 2.64x
update-center.json520.7 KB 259 557 2.15x
aggregate14.81 MB 209542 2.59x
fastjson best fastjson faster than ext/json

Per-file decode, small corpus

FileSize ext/jsonMB/s fastjsonMB/s fast/callns fastjson vsext/json
adversarial.json80 B 168 315 242 ns 1.87x
demo.json387 B 308 728 507 ns 2.36x
flatadversarial.json64 B 131 246 248 ns 1.88x
repeat.json11.1 KB 434 884 12.3 µs 2.04x
truenull.json11.7 KB 208 845 13.5 µs 4.07x
twitter_timeline.json41.2 KB 306 869 46.4 µs 2.84x
aggregate64.6 KB 295862 2.92x

Encode PHP 8.4.22-dev

fastjson 0.3.0+ encodes with a one-stage direct-write encoder (zval → smart_str via yyjson's scalar writers, no intermediate mutable document), which is where the largest wins on float- and pretty-heavy inputs come from.

ext/jsonPHP 8.4.22-dev
166 MB/s
fastjson 0.4.0PHP 8.4.22-dev
983 MB/s
05001,000 MB/s
Aggregate on the 14.81 MB large corpus. fastjson is 5.92x ext/json.

Per-file encode, large corpus

FileSize ext/jsonMB/s fastjsonMB/s fastjson vsext/json
apache_builds.json124.3 KB 1,093 1,459 1.33x
canada.json2.15 MB 56 671 12.07x
citm_catalog.json1.65 MB 2,349 2,709 1.15x
github_events.json63.6 KB 1,243 1,952 1.57x
gsoc-2018.json3.17 MB 714 1,249 1.75x
instruments.json215.2 KB 1,752 1,902 1.09x
marine_ik.json2.85 MB 125 636 5.10x
mesh.json706.6 KB 82 736 8.95x
mesh.pretty.json1.50 MB 179 1,587 8.88x
numbers.json146.6 KB 51 649 12.77x
random.json498.5 KB 589 804 1.37x
stringifiedphp.json139.9 KB 723 2,870 3.97x
twitter.json616.7 KB 1,090 1,608 1.48x
twitterescaped.json549.2 KB 981 1,412 1.44x
update-center.json520.7 KB 778 992 1.28x
aggregate14.81 MB 166983 5.92x
fastjson best ext/json faster

Per-file encode, small corpus

FileSize ext/jsonMB/s fastjsonMB/s fast/callns fastjson vsext/json
adversarial.json80 B 610 596 128 ns 0.98x
demo.json387 B 1,260 1,465 252 ns 1.16x
flatadversarial.json64 B 298 436 140 ns 1.46x
repeat.json11.1 KB 960 1,707 6.3 µs 1.78x
truenull.json11.7 KB 1,457 2,170 5.3 µs 1.49x
twitter_timeline.json41.2 KB 1,062 1,427 28.2 µs 1.34x
aggregate64.6 KB 1,0931,563 1.43x

Validate PHP 8.4.22-dev

fastjson's edge comes from vendor patch P-002 (YYJSON_READ_VALIDATE_ONLY), a no-tree validate entry point that drops peak memory ~2.7× vs the stock read path. ext/json validates by fully decoding and discarding.

ext/jsonPHP 8.4.22-dev
241 MB/s
fastjson 0.4.0PHP 8.4.22-dev
1,260 MB/s
07501,500 MB/s
Aggregate on the 14.81 MB large corpus. fastjson is 5.23x ext/json.

Per-file validate, large corpus

FileSize ext/jsonMB/s fastjsonMB/s fastjson vsext/json
apache_builds.json124.3 KB 414 2,470 5.97x
canada.json2.15 MB 104 863 8.32x
citm_catalog.json1.65 MB 551 2,457 4.46x
github_events.json63.6 KB 476 2,877 6.04x
gsoc-2018.json3.17 MB 353 1,469 4.16x
instruments.json215.2 KB 437 2,142 4.90x
marine_ik.json2.85 MB 238 821 3.45x
mesh.json706.6 KB 212 1,155 5.45x
mesh.pretty.json1.50 MB 259 1,575 6.09x
numbers.json146.6 KB 237 1,347 5.68x
random.json498.5 KB 333 1,409 4.23x
stringifiedphp.json139.9 KB 334 2,699 8.07x
twitter.json616.7 KB 502 2,431 4.84x
twitterescaped.json549.2 KB 355 2,309 6.51x
update-center.json520.7 KB 306 1,908 6.23x
aggregate14.81 MB 2411,260 5.23x
fastjson best fastjson faster than ext/json

Per-file validate, small corpus

FileSize ext/jsonMB/s fastjsonMB/s fast/callns fastjson vsext/json
adversarial.json80 B 160 652 117 ns 4.09x
demo.json387 B 360 1,425 259 ns 3.96x
flatadversarial.json64 B 161 555 110 ns 3.45x
repeat.json11.1 KB 536 1,987 5.5 µs 3.70x
truenull.json11.7 KB 232 2,314 4.9 µs 9.97x
twitter_timeline.json41.2 KB 382 2,688 15.0 µs 7.04x
aggregate64.6 KB 3572,438 6.84x

Memory peak

Single-call peak heap, fastjson / ext-json. Above 1.0 means fastjson uses more — the price of yyjson's build-a-doc-then-walk model on decode. Encode is at parity (direct-write, no mutable doc); validate trades memory for the no-tree fast path.

Decode → stdClass

ext/json56.37 MB
fastjson97.81 MB
fastjson / ext-json peak: 1.74x

Encode

ext/json11.24 MB
fastjson11.92 MB
fastjson / ext-json peak: 1.06x

Validate

ext/json150.6 KB
fastjson14.91 MB
fastjson / ext-json peak: 101.40x

Regenerate: php -d extension=modules/fastjson.so bench/run.php bench/data 300 > bench/baseline.md then php bench/render-baseline-html.php bench/baseline.md > docs/baseline.html. Source: github.com/iliaal/fastjson.