Pāriet uz saturu

Veiktspējas testi

Etalonuzdevumu ietvars veido stabilu JSON un cilvēkam lasāmu pārskatu. Tas atrodas bench/ repozitorijā storh un nav bijis daļa no Composer pakotnes kopš 0.5.2, tāpēc tālāk norādītās composer bench* komandas palaižamas tikai no klona, pēc composer install:

Apvalks
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

Etalonrezultāti

Trīs pilnu etalonuzdevumu ietvara izpildes reižu mediānas, 50,000 ieraksti katram dzinējam, uz Apple M1 Pro (16 GB, macOS 26.5, APFS) ar PHP 8.5 CLI, opcache un JIT izslēgti:

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

Katrs ieraksts tiek iztukšots un fsync sinhronizēts, pirms storh ziņo par tā saglabāšanu, tāpēc rakstīšanas ātrumu ierobežo failu sistēma. Lasīšana notiek no operētājsistēmas lapu kešatmiņas. Ātrumi aprēķināti no mediānām; palaidiet composer bench no repozitorija klona, lai pārbaudītu savu aparatūru.

DocStore, 50k ieraksti mediāna
put(), viens noturīgs fails katram ierakstam 3.3k ieraksti/s
putStream() lielapjoma ievade 3.7k ieraksti/s
importJsonl() 3.6k ieraksti/s
get() atsevišķa nolasīšana, STAT pārbaudīta 5.6 µs
esošas krātuves atkārtota atvēršana 0.26 ms
indeksēts vienādības vaicājums, limit(100) 1.1 ms
indeksēta count() visā kolekcijā 41 µs
indeksa izveide, 2 vienādības + 1 diapazona lauks 52k ieraksti/s
pilna stream() ar atkārtotu STAT pārbaudi 103k ieraksti/s
exportJsonl() 104k ieraksti/s
SegmentedLog, 50k ieraksti, 16 KB segmenti mediāna
put(), fsync pēc katras pievienošanas 16k pievienošanas/s
appendStream() lielapjoma ievade 56k ieraksti/s
kursora nolasīšana, 100 ieraksti no viduspunkta 2.1 ms
laika diapazona nolasīšana 1.1 ms
vienādības count() 11 µs
compact() visi noslēgtie segmenti 69k ieraksti/s
atkārtota atvēršana pēc nepilnīgu beigu datu atkopšanas 218k ieraksti/s

Etalonuzdevumā ik pēc 16 KB tiek noslēgts segments, lai pārbaudītu segmentu maiņu; noklusētais segmenta izmērs ir 1 MiB.

Rinda, 50k uzdevumi mediāna
enqueue(), fsync pēc katra notikuma 22k uzdevumi/s
claim() 23k uzdevumi/s
complete() 23k uzdevumi/s
enqueueMany() 209k uzdevumi/s
claimMany() 467k uzdevumi/s
completeMany() 512k uzdevumi/s
SQL Mirror, SQLite, 50k ieraksti mediāna
sākotnējā push() 61k rindas/s
push() bez izmaiņām 86k ieraksti/s
flush(), 100 ID 7.1 ms
indeksēta SQL COUNT spoguļa kopā 6.9 ms
rebuild() 65k rindas/s
pull() atjaunošana, viens noturīgs fails katram ierakstam 3.2k ieraksti/s
Mikro mediāna
kešota get(), auksta, tad silta (MemoryCache, STAT) 83 µs / 6.3 µs
UUIDv7 ģenerēšana 1.3 µs
UUIDv7 pārbaude 0.30 µs
predikātu filtrēšana atmiņā 4.4M rindas/s

Aptvertie mērķi:

  • DocStore put, straumēšanas put, JSONL eksportēšana/importēšana, get, delete, stream un indeksa izveide
  • vienādības, saliktā un diapazona indeksa vaicājumi, sakārtoti diapazoni augošā un dilstošā secībā, indeksēšana pēc skaita, ID meklēšana un neindeksēti DocStore vaicājumi
  • SegmentedLog append, straumēšanas append, kursora nolasīšana, laika diapazona nolasīšana, saspiesta laika diapazona nolasīšana, QueryBuilder kursora un ID meklēšana, skaits, lielapjoma append skaits, statistika, saspiešana
  • Queue enqueue, lielapjoma enqueue, claim, lielapjoma claim, complete, lielapjoma complete, requeue
  • RecordQuery un QueryCondition predikātu filtrēšana atmiņā esošajās rindās
  • UUIDv7 monotonā ģenerēšana, ģenerēšana ar izkliedētiem laika zīmogiem, pārbaude un laika zīmoga izgūšana
  • nepilnīgas beigu rindas atkopšana
  • aukstas un siltas kešatmiņas nolasīšana ar jaukšanas, stat vai uzticamu pārbaudi

Noklusētais izvades ceļš:

Text
build/bench-current.json

Diapazona etalonuzdevumi raksta vienu JSON failu katrai datu kopai un dzinējam mapē build/bench-ranges/.

bench:gate salīdzina divus etalonuzdevumu JSON failus un izvada statusu, kas nav nulle, ja kāda izsekojamā metrika ir lēnāka par konfigurēto slieksni. Ja netiek norādītas --metric vērtības, tiek pārbaudīta katra bāzes failā esošā metrika.

bench:ci ir GitHub Actions regresiju pārbaudei. Tā palaiž visu dzinēju 1k etalonuzdevumu, salīdzina atlasītās rakstīšanas, lasīšanas, kešatmiņas un UUID metrikas ar izsekoto bench/baselines/ci-1k-all.json bāzes vērtību un izmanto plašu noklusēto slieksni, lai izvairītos no parastajām izpildvides svārstībām, vienlaikus atklājot būtiskas veiktspējas regresijas.

bench:jit palaiž to pašu etalonuzdevumu ietvaru ar iespējotu CLI opcache un izsekošanas JIT, kā arī atspējo Xdebug etalonuzdevuma procesam, lai PHP tiešām varētu ieslēgt JIT. Izveidotajā JSON ir iekļauti izpildvides karodziņi, kas parāda, vai šajā izpildē opcache un JIT bija aktīvi.