This folder contains a tiny, allocation-free hot-loop benchmark client:
- It opens one or more TCP connections.
- It repeatedly writes a pre-rendered HTTP/1.1 request string (minimal request by default).
- It discards a fixed number of bytes per response (no HTTP parsing in the hot loop).
zig build bench -Doptimize=ReleaseFast -- --mode=zhttp --conns=1 --iters=100000 --warmup=10000Convenience runner (environment-driven defaults):
CONNS=1 ITERS=100000 WARMUP=10000 zig run benchmark/run_zhttp.zigRuns zhttp-bench-server and benchmarks it via the same client in --mode=external:
zig run benchmark/run_zhttp_external.zig
# or
zig build benchrun_zhttp_external writes benchmark/results/bench_latest.json and
benchmark/results/bench_latest.md, and refreshes the README fetch section.
FaF is benchmarked against the faf-example app (/plaintext on port 8080).
zig run benchmark/run_faf.zig clones both faf-example and faf into .zig-cache/faf-example and
.zig-cache/faf, pins FaF to the revision in Cargo.lock, and applies a tiny compatibility patch
(for newer Rust nightly intrinsics) before building. It expects zhttp-bench to be available;
set BENCH_BIN to a built bench binary path or build it first.
BENCH_BIN=./zig-out/bin/zhttp-bench zig run benchmark/run_faf.zigRuns both servers with the same benchmark client settings (defaults: FULL_REQUEST=1, CONNS=16, REUSE=1):
- identical
host/path/conns/iters/warmup/full_request/reuse - fixed response bytes discovered twice per target and pinned for the timed run
zig run benchmark/run_compare.zig
# or
zig build bench-comparerun_compare writes:
benchmark/results/latest.jsonbenchmark/results/latest.md
and refreshes README comparison/fetch sections.
To point at an already running server:
zig build bench -Doptimize=ReleaseFast -- --mode=external --host=127.0.0.1 --port=8080 --path=/plaintextNotes:
--hostis currently expected to be an IPv4 literal.- If
--fixed-bytesis not provided, the benchmark auto-discoversContent-Lengthonce (outside the hot loop). run_zhttp_external.zigandrun_faf.zigboth validate response size stability by discovering fixed bytes twice before timing.run_compare.zignow uses a dedicated FaF no-reuse example template so the no-reuse comparison matches zhttp's close-response byte count too.- Use
--full-requestto sendHost:andConnection:headers (default is the minimalGET ...\r\n\r\nrequest). --reuse=1(default) reuses one keep-alive connection per worker; use--reuse=0/--no-reuseto reconnect every request.zhttp-bench-serverusescpu_countpermanent workers in both reuse modes.- For zhttp server config, prefer
.temp_worker_spawn = .pollingfor keep-alive-heavy (--reuse=1) traffic and.temp_worker_spawn = .signaledfor reconnect-heavy (--reuse=0) traffic. - For the helper scripts, set
FULL_REQUEST=1to pass--full-request:FULL_REQUEST=1 zig run benchmark/run_zhttp_external.zigFULL_REQUEST=1 zig run benchmark/run_faf.zig
- For helper scripts, set
REUSE=0to disable reuse:REUSE=0 zig run benchmark/run_zhttp_external.zigREUSE=0 zig run benchmark/run_faf.zig
run_perf.zig replaces the old shell helper and records/report profiles by driving zhttp-bench:
MODE=zhttp CONNS=1 ITERS=100000 WARMUP=10000 zig run benchmark/run_perf.zig