A teaching repo to compare concurrency behavior across Go / Python / Rust under the same workload contract.
Current implemented phase:
- Workload:
cpu_hash(CPU-bound) - Modes:
- Python:
single,threads,process,async - Go:
single,threads,process(goroutinesalias to thread worker pool) - Rust:
single,threads,process
- Python:
- Unified JSON metrics output for all languages
- Unified summarizer: CSV + Markdown report
Interview prep often asks:
- Why Python threads may not speed up CPU-bound tasks (GIL)
- Why process pools can help CPU-bound workloads
- How Go goroutines and Rust threads differ in ergonomics and overhead
- How to compare throughput/latency fairly across languages
This repo gives deterministic, reproducible runs to answer those quickly.
See workloads/spec.md.
cpu_hashis implemented.io_files,mixed_pipeline,fanout_faninare scaffolded for next phase.
./scripts/run_all.shOutputs:
results/latest/*.jsonresults/latest/summary.csvresults/latest/summary.md
Python:
PYTHONPATH=python/src python -m runner \
--workload cpu_hash --mode process --tasks 120 --concurrency 4 --payload 256 --iters 200 \
--output results/latest/py_cpu_hash_process.json --seed 42Go:
cd go
go run ./cmd/runner --workload cpu_hash --mode process --tasks 120 --concurrency 4 --payload 256 --iters 200 --output ../results/latest/go_cpu_hash_process.json --seed 42Rust:
cd rust
cargo run --release -- --workload cpu_hash --mode process --tasks 120 --concurrency 4 --payload 256 --iters 200 --output ../results/latest/rs_cpu_hash_process.json --seed 42Each run writes JSON with:
meta: language/version/workload/mode/tasks/concurrency/payload/iters/warmup/timestamp/env/seedmetrics: wall time, throughput, latency p50/p95/p99, optional CPU/RSS, errors, checksum samples
cpu_hashis CPU-bound:- Python:
processtypically outperformsthreadsfor CPU-heavy tasks. - Go/Rust: threaded execution usually scales better with available cores.
- Python:
- Use the same
tasks/payload/iterswhen comparing languages. - CI runner numbers and local machine numbers are expected to differ.
- Python GIL can limit CPU-bound thread speedups.
- Process mode has serialization and startup overhead.
- Goroutines are lightweight but still have scheduling/GC costs.
- Async is mainly useful for I/O-bound workloads, not pure CPU hashing.
workloads/spec.md: workload contract and correctness rulesscripts/run_all.sh: one-command benchmark launcherscripts/summarize.py: JSON -> CSV/Markdown summarypython/src/runner: Python CLI runnergo/cmd/runner: Go CLI runnerrust/src/main.rs: Rust CLI runner.github/workflows/bench.yml: minimal CI benchmark
- This phase intentionally uses minimal dependencies.
- Missing toolchains are skipped by
run_all.shwith clear logs.