Ga naar de inhoud

Benchmarks

Het benchmarkharnas schrijft stabiele JSON en een leesbaar rapport. Het staat in bench/ in de repository storh en maakt sinds 0.5.2 geen deel meer uit van het pakket Composer, dus de onderstaande composer bench*- commando's voert u alleen uit vanuit een kloon, na 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

Referentieresultaten

Medianen van drie volledige runs van het harnas, 50,000 records per engine, op een Apple M1 Pro (16 GB, macOS 26.5, APFS) met PHP 8.5 CLI, opcache en JIT uitgeschakeld:

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

Elke schrijfbewerking wordt geflusht en gefsynct voordat storh meldt dat deze is opgeslagen, dus de schrijfsnelheid wordt begrensd door het bestandssysteem. Leesbewerkingen gebruiken de OS-paginacache. Snelheden zijn afgeleid van de medianen; voer composer bench uit vanuit een kloon van de repository voor uw eigen hardware.

DocStore, 50k records mediaan
put(), één duurzaam bestand per record 3.3k records/s
putStream() bulkopname 3.7k records/s
importJsonl() 3.6k records/s
get() puntlezing, STAT-gevalideerd 5.6 µs
bestaande store opnieuw openen 0.26 ms
geïndexeerde gelijkheidsquery, limit(100) 1.1 ms
geïndexeerde count() door de hele collectie 41 µs
index opbouwen, 2 gelijkheidsvelden + 1 bereikveld 52k records/s
volledige stream() met STAT-herbevestiging 103k records/s
exportJsonl() 104k records/s
SegmentedLog, 50k records, segmenten van 16 KB mediaan
put(), fsync per toevoeging 16k toevoegingen/s
appendStream() bulkopname 56k records/s
cursorlezing, 100 records vanaf het midden 2.1 ms
lezing over een tijdsbereik 1.1 ms
gelijkheidscount() 11 µs
compact() alle verzegelde segmenten 69k records/s
opnieuw openen met herstel van onvolledige staart 218k records/s

De benchmark verzegelt elke 16 KB een segment om het wisselen van segmenten te belasten; de defaultsegmentgrootte is 1 MiB.

Queue, 50k taken mediaan
enqueue(), fsync per gebeurtenis 22k taken/s
claim() 23k taken/s
complete() 23k taken/s
enqueueMany() 209k taken/s
claimMany() 467k taken/s
completeMany() 512k taken/s
SQL Mirror, SQLite, 50k records mediaan
initiële push() 61k rijen/s
push() zonder wijzigingen 86k records/s
flush(), 100 ids 7.1 ms
geïndexeerde SQL COUNT over de mirror 6.9 ms
rebuild() 65k rijen/s
pull() herstellen, één duurzaam bestand per record 3.2k records/s
Micro mediaan
gecachte get(), koud dan warm (MemoryCache, STAT) 83 µs / 6.3 µs
UUIDv7 genereren 1.3 µs
UUIDv7 valideren 0.30 µs
predicatefiltering in het geheugen 4.4M rijen/s

Gedekte doelen:

  • DocStore put, streaming put, JSONL export/import, get, delete, stream en indexopbouw
  • geïndexeerde gelijkheids-, samengestelde index- en bereikquery's, oplopende en aflopende geordende bereiken, geïndexeerde telling, ID-lookup en niet-geïndexeerde DocStore-query's
  • SegmentedLog append, streaming append, cursorlezingen, lezingen over tijdsbereiken, lezingen over gecompacteerde tijdsbereiken, QueryBuilder-cursor- en ID-lookups, tellingen, tellingen van bulk-appends, statistieken en compactie
  • Queue enqueue, bulk enqueue, claim, bulk claim, complete, bulk complete en requeue
  • predicatefiltering met RecordQuery en QueryCondition over rijen in het geheugen
  • UUIDv7 monotone generatie, generatie met gespreide tijdstempels, validatie en extractie van tijdstempels
  • herstel van onvolledige afsluitende regels
  • koude en warme cachelezingen met hash-, stat- of vertrouwde validatie

Standaarduitvoerpad:

Text
build/bench-current.json

Bereikruns schrijven één JSON-bestand per dataset en engine onder build/bench-ranges/.

bench:gate vergelijkt twee benchmark-JSON-bestanden en eindigt met een niet-nulstatus als een gevolgde metriek trager is dan de ingestelde drempel. Als er geen --metric-waarden worden opgegeven, controleert het alle metrieken in het baselinebestand.

bench:ci is de GitHub Actions rookregressietest. Deze voert een 1k-benchmark voor alle engines uit, vergelijkt geselecteerde schrijf-, lees-, cache- en UUID-statistieken met de bijgehouden bench/baselines/ci-1k-all.json-baseline en gebruikt een ruime standaarddrempel om normale runner-ruis te vermijden en toch grote prestatieregressies te detecteren.

bench:jit voert hetzelfde harnas uit met CLI-opcache en tracing JIT ingeschakeld, en schakelt Xdebug uit voor het benchmarkproces zodat PHP JIT daadwerkelijk kan inschakelen. De gegenereerde JSON bevat runtimevlaggen die aangeven of opcache en JIT actief waren tijdens die run.