Skip to content

Run a Benchmark

Datum ships Criterion micro-benchmarks for every operator area and a set of head-to-head comparison runners that pit Datum against warmed Akka/Pekko Streams.

Criterion benchmarks (Datum only)

No JDK required. Run from the repo root:

sh
cargo bench --bench push_baseline    # sanity baseline
cargo bench --bench source_flow      # Source/Flow operators
cargo bench --bench materialization  # graph construction, materialization, sink terminals
cargo bench --bench graph            # GraphDSL, fused executor, junctions
cargo bench --bench actor_ask        # ActorFlow::ask throughput, latency, timeout
cargo bench --bench dynamic_streams  # KillSwitch, MergeHub, BroadcastHub, PartitionHub
cargo bench --bench streaming_io     # file I/O, compression, framing, TCP
cargo bench --bench queues           # SourceQueue, BoundedSourceQueue, SinkQueue
cargo bench --bench substreams       # flat_map_concat/merge, split_when/after, group_by

Each bench produces an HTML report under target/criterion/<bench-name>/.

Datum vs. Akka comparison (requires JDK + sbt)

The comparison harness builds a Datum release runner and the matching Akka JMH benchmark, then renders a shared table. Each runner lives under crates/datum-core/benches/<area>_compare/:

sh
crates/datum-core/benches/source_flow_compare/run.sh
crates/datum-core/benches/materialization_compare/run.sh
crates/datum-core/benches/graph_compare/run.sh
crates/datum-core/benches/actor_ask_compare/run.sh
crates/datum-core/benches/dynamic_streams_compare/run.sh
crates/datum-core/benches/streaming_io_compare/run.sh
crates/datum-core/benches/substreams_compare/run.sh
crates/datum-core/benches/queues_compare/run.sh

Each runner pairs with an Akka JMH class under crates/datum-core/benches/akka-jmh/. The Akka side runs under fair JMH warmup (-wi 5 -i 5 -w 1s -r 1s). The Datum side adds a Datum CPU us/op column derived from /proc/self/stat — a process CPU time measurement that is deliberately separate from wall-clock. Some Datum wins come partly from busy-spinning while Akka parks; the CPU column makes that cost visible.

Network comparison

The network comparison harness covers datum-net and works the same way:

sh
crates/datum-core/benches/net_compare/run.sh

This runs Datum and Akka side-by-side on TLS echo, UDP send/receive, and remote StreamRefs (plaintext TCP + encrypted QUIC). The Akka harness now forces real Artery-TCP remoting for StreamRefs and measures whole-process CPU via ProcfsProfiler.

Reading the results

Current result tables live in roadmap/benchmarks/:

  • source-flow.md — Source/Flow operators
  • materialization.md — construction, materialization latency, sink terminals
  • graph.md — GraphDSL, junctions, fused executor
  • actor-ask.md — ActorFlow::ask ordered/unordered, timeout
  • dynamic-streams.md — KillSwitch, MergeHub, BroadcastHub, PartitionHub
  • streaming-io.md — file I/O, compression, framing, TCP
  • substreams.md — flat_map_concat/merge, split_when/after, group_by
  • queues.md — SourceQueue, BoundedSourceQueue, SinkQueue
  • net.md — TLS, UDP, QUIC, remote StreamRefs, async carriers, sharding

The tables include both wall-clock (Datum us/op) and CPU (Datum CPU us/op) columns. A path that wins on wall-clock but loses on CPU is spending that CPU on spin-polling. Datum reports it honestly rather than hiding it.

See roadmap/milestones/M1-v0.1.0-foundation.md for the apples-to-apples caveats and the per-operator coverage matrix.