Gå til indhold

Benchmarkresultater

Benchmark-harnessen skriver stabile JSON og en rapport, der er let at læse. Den ligger i bench/ i storh-repositoryet og har ikke været en del af pakken Composer siden 0.5.2, så composer bench*-kommandoerne nedenfor kan kun køres fra en klon, efter 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

Referenceresultater

Medianer fra tre fulde kørsler af værktøjet med 50,000 poster pr. motor på en Apple M1 Pro (16 GB, macOS 26.5, APFS) med PHP 8.5 CLI, opcache og JIT slået fra:

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

Hver skrivning tømmes og fsync-køres, før storh melder, at den er gemt, så skrivehastigheden begrænses af filsystemet. Læsninger bruger operativsystemets sidecache. Hastighederne er beregnet ud fra medianerne. Kør composer bench fra en klon af repositoryet for at måle din egen hardware.

DocStore, 50k poster median
put(), én varig fil pr. post 3.3k poster/s
putStream() masseindlæsning 3.7k poster/s
importJsonl() 3.6k poster/s
get() punktlæsning, STAT-valideret 5.6 µs
genåbning af et eksisterende lager 0.26 ms
indekseret lighedssøgning, limit(100) 1.1 ms
indekseret count() på tværs af samlingen 41 µs
indeksbygning, 2 lighedsfelter + 1 intervalfelt 52k poster/s
fuld stream() med STAT-genvalidering 103k poster/s
exportJsonl() 104k poster/s
SegmentedLog, 50k poster, 16 KB-segmenter median
put(), fsync ved hver tilføjelse 16k tilføjelser/s
appendStream() masseindlæsning 56k poster/s
markørlæsning, 100 poster fra midten 2.1 ms
intervalaflæsning efter tid 1.1 ms
lighedssøgning count() 11 µs
compact() alle forseglede segmenter 69k poster/s
genåbning med gendannelse af afbrudt afslutning 218k poster/s

Benchmarken forsegler et segment for hver 16 KB for at stresse segmentskift; standardsegmentstørrelsen er 1 MiB.

Kø, 50k job median
enqueue(), fsync for hver hændelse 22k job/s
claim() 23k job/s
complete() 23k job/s
enqueueMany() 209k job/s
claimMany() 467k job/s
completeMany() 512k job/s
SQL Mirror, SQLite, 50k poster median
indledende push() 61k rækker/s
push() uden ændringer 86k poster/s
flush(), 100 id'er 7.1 ms
indekseret SQL COUNT i hele spejlet 6.9 ms
rebuild() 65k rækker/s
pull()-gendannelse, én varig fil pr. post 3.2k poster/s
Mikro median
cachelagret get(), kold derefter varm (MemoryCache, STAT) 83 µs / 6.3 µs
UUIDv7 generér 1.3 µs
UUIDv7 validér 0.30 µs
filtrering med in-memory-predicate 4.4M rækker/s

Dækkede mål:

  • DocStore put, streaming put, JSONL eksport/import, get, delete, stream og indeksopbygning
  • lighedsindekserede, sammensat-indekserede, områdeindekserede, stigende og faldende ordnede områdeforespørgsler, indekseret optælling, ID-opslag og ikke-indekserede DocStore-forespørgsler
  • SegmentedLog append, streaming append, markørlæsninger, tidsområdelæsninger, komprimerede tidsområdelæsninger, QueryBuilder-markør- og ID-opslag, optællinger, masseappend-optællinger, statistik, komprimering
  • Queue enqueue, masse-enqueue, claim, masse-claim, complete, masse-complete, requeue
  • filtrering med RecordQuery- og QueryCondition-predicate over rækker i hukommelsen
  • UUIDv7 monoton generering, generering med tidsstempelfordeling, validering og udtræk af tidsstempel
  • gendannelse efter afbrudt afsluttende linje
  • kolde og varme cachelæsninger med hash-, stat- eller betroet validering

Standardsti for output:

Text
build/bench-current.json

Områdekørsler skriver én JSON-fil pr. datasæt og motor under build/bench-ranges/.

bench:gate sammenligner to benchmarkfiler JSON og afslutter med en statuskode, der ikke er nul, hvis en målt metrik er langsommere end den konfigurerede tærskel. Hvis der ikke angives nogen --metric-værdier, kontrolleres alle metrikker i baselinefilen.

bench:ci er GitHub Actions-røggaten for regressioner. Den kører en benchmark med 1k for alle motorer, sammenligner udvalgte målinger for skrivning/læsning/cache/UUID med den registrerede bench/baselines/ci-1k-all.json-baseline og bruger en bred standardtærskel for at undgå normal støj fra kørsler, samtidig med at den stadig fanger store ydelsesregressioner.

bench:jit kører samme testopsætning med CLI opcache og sporings-JIT aktiveret og deaktiverer Xdebug for benchmarkprocessen, så PHP faktisk kan aktivere JIT. Den genererede JSON indeholder kørselsflag, der viser, om opcache og JIT var aktive under kørslen.