Lewati ke konten

Tolok Ukur

Harness benchmark menulis JSON yang stabil dan laporan yang mudah dibaca. Lokasinya ada di bench/ dalam repositori storh dan tidak lagi menjadi bagian dari paket Composer sejak 0.5.2, jadi perintah composer bench* di bawah hanya dapat dijalankan dari hasil clone, setelah composer install:

Shell
composer bench
composer bench -- --dataset=100000 --engine=doc
composer bench -- --dataset=100000 --engine=log
composer bench -- --dataset=100000 --engine=queue
composer bench -- --dataset=100000 --engine=cache --cache-validation=trust
composer bench -- --dataset=100000 --engine=filter
composer bench -- --dataset=1000000 --engine=uuid
composer bench:jit -- --dataset=1000000 --engine=uuid
composer bench:repeat -- --dataset=100000 --engine=doc --repeat=5
composer bench:repeat -- --dataset=1000000 --engine=filter --repeat=5 --memory-limit=512M
composer bench:range -- --datasets=1000,10000,50000,100000
composer bench:range -- --datasets=100000 --engines=cache --memory-limit=512M
composer bench:compare build/bench-main.json build/bench-current.json
composer bench:gate -- build/bench-main.json build/bench-current.json --threshold=10 --metric=doc.put --metric=log.stream
composer bench:ci

Hasil referensi

Median dari tiga proses harness penuh, 50,000 record per mesin, pada Apple M1 Pro (16 GB, macOS 26.5, APFS) dengan PHP 8.5 CLI, opcache dan JIT dinonaktifkan:

Shell
composer bench:repeat -- --dataset=50000 --engine=all --repeat=3 --memory-limit=512M

Setiap penulisan di-flush dan di-fsync sebelum storh melaporkan bahwa data telah tersimpan, sehingga laju penulisan dibatasi oleh sistem file. Pembacaan dilakukan terhadap cache halaman OS. Laju dihitung dari median; jalankan composer bench dari hasil clone repositori untuk mengukur perangkat keras Anda sendiri.

DocStore, 50k record median
put(), satu file persisten per record 3.3k record/s
putStream() ingest massal 3.7k record/s
importJsonl() 3.6k record/s
get() pembacaan titik, divalidasi STAT 5.6 µs
membuka kembali store yang ada 0.26 ms
kueri kesetaraan berindeks, limit(100) 1.1 ms
count() berindeks di seluruh koleksi 41 µs
pembangunan indeks, 2 field kesetaraan + 1 field rentang 52k record/s
stream() penuh dengan validasi ulang STAT 103k record/s
exportJsonl() 104k record/s
SegmentedLog, 50k record, segmen 16 KB median
put(), fsync per append 16k append/s
appendStream() ingest massal 56k record/s
pembacaan kursor, 100 record dari titik tengah 2.1 ms
pembacaan rentang waktu 1.1 ms
count() kesetaraan 11 µs
compact() semua segmen tersegel 69k record/s
membuka ulang dengan pemulihan akhir terpotong 218k record/s

Benchmark menyegel segmen setiap 16 KB untuk menguji pergantian segmen; ukuran segmen bawaan adalah 1 MiB.

Queue, 50k pekerjaan median
enqueue(), fsync per peristiwa 22k pekerjaan/s
claim() 23k pekerjaan/s
complete() 23k pekerjaan/s
enqueueMany() 209k pekerjaan/s
claimMany() 467k pekerjaan/s
completeMany() 512k pekerjaan/s
SQL Mirror, SQLite, 50k record median
push() awal 61k baris/s
push() tanpa perubahan 86k record/s
flush(), 100 id 7.1 ms
SQL berindeks COUNT di seluruh mirror 6.9 ms
rebuild() 65k baris/s
restore pull(), satu file persisten per record 3.2k record/s
Mikro median
get() yang di-cache, cold lalu warm (MemoryCache, STAT) 83 µs / 6.3 µs
generasi UUIDv7 1.3 µs
validasi UUIDv7 0.30 µs
penyaringan predikat dalam memori 4.4M baris/s

Target yang dicakup:

  • DocStore put, streaming put, ekspor/impor JSONL, get, delete, stream, dan pembangunan indeks
  • kueri DocStore dengan indeks kesetaraan, indeks gabungan, indeks rentang, rentang berurutan naik dan turun, hitung terindeks, pencarian ID, dan tanpa indeks
  • SegmentedLog append, streaming append, pembacaan kursor, pembacaan rentang waktu, pembacaan rentang waktu hasil pemadatan, pencarian kursor dan ID QueryBuilder, hitung, hitung append massal, statistik, pemadatan
  • Queue enqueue, enqueue massal, claim, claim massal, complete, complete massal, requeue
  • penyaringan predikat RecordQuery dan QueryCondition pada baris dalam memori
  • generasi monotonik UUIDv7, generasi sebaran timestamp, validasi, dan ekstraksi timestamp
  • pemulihan baris akhir yang terpotong
  • pembacaan cache cold dan warm dengan validasi hash, stat, atau tepercaya

Jalur output bawaan:

Text
build/bench-current.json

Proses rentang menulis satu file JSON per dataset dan mesin di bawah build/bench-ranges/.

bench:gate membandingkan dua file benchmark JSON dan keluar dengan status non-zero jika metrik yang dipantau mana pun lebih lambat daripada ambang yang dikonfigurasi. Jika tidak ada nilai --metric yang diberikan, semua metrik dalam file baseline akan menjadi pengujian batas.

bench:ci adalah gerbang regresi smoke GitHub Actions. Ini menjalankan benchmark 1k untuk semua mesin, membandingkan metrik tulis/baca/cache/UUID yang dipilih dengan baseline bench/baselines/ci-1k-all.json yang dipantau, dan menggunakan ambang bawaan yang lebar untuk menghindari variasi normal runner sambil tetap menggagalkan regresi kinerja yang besar.

bench:jit menjalankan harness yang sama dengan opcache CLI dan tracing JIT diaktifkan, serta menonaktifkan Xdebug untuk proses benchmark agar PHP benar-benar dapat mengaktifkan JIT. JSON yang dihasilkan menyertakan flag runtime yang menunjukkan apakah opcache dan JIT aktif pada proses tersebut.