Scripts for benchmarking
Project description
porter_bench
A Python benchmarking library for measuring execution time and memory usage across named pipeline steps and training loop iterations.
Installation
pip install -e ".[dev]"
pre-commit install
# or
make install
Quick start
from porter_bench import bench_dict
for i in range(10):
bench_dict["my_pipeline"].gstep() # boundary between iterations
data = load()
bench_dict["my_pipeline"].step("load")
result = process(data)
bench_dict["my_pipeline"].step("process")
bench_dict["my_pipeline"].gstop()
bench_dict.save() # writes JSON files to TICTOC_PERFORMANCE/<timestamp>/
Usage
Pipeline benchmarking
bench_dict["name"] lazily creates a Benchmarker. The gstep/gstop pair marks iteration boundaries; step(topic) records time for a named sub-step within that iteration.
from porter_bench import bench_dict
bench = bench_dict["pipeline"]
bench.set_save_on_gstop(4) # auto-save every 4 iterations
for _ in range(20):
bench.gstep()
bench.step("load")
bench.step("compute")
bench.step("postprocess")
bench.gstop()
bench_dict.save()
Training loop with IterBench
IterBench wraps any iterable and calls gstep()/gstop() automatically around each iteration:
from porter_bench import bench_dict
from porter_bench.GlobalBenchmarker import IterBench
for batch in IterBench(dataloader, bench_dict, "training"):
bench_dict["training"].step("forward")
bench_dict["training"].step("backward")
Memory tracking
bench = bench_dict["memory"]
bench.enable_memory_tracking(per_step=True) # RAM tracking per step
bench.memory_benchmaker.enable_max_memory(poll_time=0.05) # peak RAM polling
# Optional CUDA tracking (requires torch with CUDA)
bench.memory_benchmaker.enable_cuda_memory_tracking()
Low-level timer utilities
from porter_bench import timer
from porter_bench.basic import CountDownClock, TimedCounter
# Simple timer
timer.tic()
result = do_work()
elapsed = timer.toc() # seconds since tic
elapsed = timer.ttoc() # toc + reset
# Countdown
clock = CountDownClock(count_down_time=4.0)
while not clock.completed():
print("time left:", clock.time_left())
# Frequency counter
counter = TimedCounter()
counter.start()
for _ in range(100):
do_work()
counter.count()
counter.stop()
print("frequency:", counter.get_frequency(), "Hz")
Auto-save options
bench.set_save_on_gstop(N) # save every N iterations
bench.set_save_on_step(True) # save after every step
Loading and visualising results
from porter_bench.utils import load_record
from porter_bench.DataHandler import DataHandler
record = load_record(".") # loads latest run from TICTOC_PERFORMANCE/
handler = DataHandler({"run": record})
handler.plot_times(record_name="pipeline")
handler.make_bars(record_name="pipeline")
handler.plot_crono(record_name="pipeline")
handler.plot_memory_usage(record_name="memory")
Or run the standalone script after make example:
python generate_plots.py --path . --output PLOTS --show
Plots are saved to PLOTS/ as <name>_times.png, <name>_bars.png, <name>_crono.png, <name>_memory.png.
Output files
All JSON files are written under TICTOC_PERFORMANCE/<timestamp>/<name>/:
| File | Contents |
|---|---|
*_STEP_DICT_DATA.json |
Per-iteration step timings |
*_STEP_DICT_SUMMARY.json |
Aggregated mean/min/max stats |
*_MEMORY.json |
RAM and CUDA memory snapshots |
Development
make test # pytest
make lint # pre-commit run --all-files
make example # run example.py then generate_plots.py
TICTOC_TOGGLES
TICTOC_TOGGLES is an 8-bit binary string environment variable that exposes boolean feature flags for automating test variations without code changes. Each bit position is an independent toggle (index 0 = rightmost bit).
TICTOC_TOGGLES="00000001" pytest # toggle 0 on
TICTOC_TOGGLES="00000011" pytest # toggles 0 and 1 on
TICTOC_TOGGLES="10000000" pytest # toggle 7 on
Inside the library, TICTOC_TOGGLES is parsed into a list[bool] of length 8, importable as:
from porter_bench import TICTOC_TOGGLES
if TICTOC_TOGGLES[0]:
# behaviour variant A
else:
# behaviour variant B
This lets you drive conditional code paths — alternative algorithms, stricter assertions, extra logging — purely from the environment, making it easy to test both branches in CI or a single pytest run.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file porter_bench-0.2.0.tar.gz.
File metadata
- Download URL: porter_bench-0.2.0.tar.gz
- Upload date:
- Size: 36.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79063c2ee888bf984efd50403da3e867fe2cab1e802c64ae1250a4fc2b1d0f50
|
|
| MD5 |
14106963e113b24112105e9d2be4398a
|
|
| BLAKE2b-256 |
6c9212cd513fb090b1f3457e260ad4da5e26e5927eb47fbaf5e078a70f5cc19a
|
File details
Details for the file porter_bench-0.2.0-py3-none-any.whl.
File metadata
- Download URL: porter_bench-0.2.0-py3-none-any.whl
- Upload date:
- Size: 36.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8338f3a87d9559837e1a530fd6120265483e240b63b7feeccfae084f2302fee5
|
|
| MD5 |
40bbd40af5147c0fecbc6f33e6562f2e
|
|
| BLAKE2b-256 |
c95ac1be453b5c802b59baa3d4a03f7f3596c82846f98e312be82067a2657b7f
|