lbench - Benchmarking Tool for Python Projects
lbench is a benchmarking tool built on top of pytest and pytest-benchmark, designed to make it easy to write, run, and analyze benchmarks for Python projects. It provides automatic result logging, cProfile profiling and flamegraphs, Dask performance reporting, memory tracking, a Jupyter notebook magic, and a dashboard for visualizing and comparing benchmark results over time.
Installation
git clone https://github.com/yourusername/lsdb-benchmarking.git
cd lsdb-benchmarking
pip install -e .
Writing Benchmarks
Basic Benchmarks with lbench Fixture
The lbench fixture extends pytest-benchmark with automatic cProfile profiling:
def test_my_function(lbench):
def benchmark_func():
result = my_function()
lbench(benchmark_func)
Add @pytest.mark.lbench_memory to also track peak memory usage with memray:
@pytest.mark.lbench_memory
def test_my_function(lbench):
lbench(my_function)
Dask Benchmarks with lbench_dask Fixture
def test_my_dask_function(lbench_dask):
def benchmark_func():
result = my_dask_dataframe.compute()
lbench_dask(benchmark_func)
The lbench_dask fixture automatically collects Dask task stream information, generates a Dask performance
report, and samples memory usage during execution. Use lbench_dask_collection to also record the Dask graph
size and node count:
def test_collection(lbench_dask_collection):
catalog = lsdb.read_hats(...)
lbench_dask_collection(catalog)
Running Benchmarks
pytest --lbench benchmarks/
This creates a timestamped result directory, runs all benchmarks, and saves:
pytest-benchmark.json— timing stats and extra metricscprofile_*.prof— cProfile data for each benchmarkdask_performance_report_*.html— Dask performance reports (Dask benchmarks only)memray_*.bin— memory tracking data (memory-marked benchmarks only)
Configuring the Result Directory
# Via flag
pytest --lbench --lbench-root=/path/to/results benchmarks/
# Via environment variable
export LBENCH_ROOT=/path/to/results
pytest --lbench benchmarks/
If neither is set, results are saved to ./lbench_results.
Running Benchmarks in Jupyter Notebooks
lbench provides a %%lbench cell magic that produces the same JSON log format as the pytest runner,
so notebook results appear alongside pytest results in the dashboard.
Load the extension once per notebook:
%load_ext
lbench.notebook
Then use the cell magic on any cell:
%%lbench
my_expensive_function()
With options:
%%lbench - -rounds
10 - -warmup - -memory - -profile - -name
my_benchmark
my_expensive_function()
Available options:
| Option | Short | Description |
|---|---|---|
--rounds N |
-r |
Number of timed rounds (default: 5) |
--warmup |
-w |
Run one un-timed warmup round first |
--memory |
-m |
Track peak memory with memray |
--profile |
-p |
Capture a cProfile .prof file |
--dask |
-d |
Collect Dask metrics (task stream, memory, performance report) |
--collection VAR |
Also record graph size/length from a Dask collection variable | |
--name NAME |
-n |
Name for this benchmark entry |
Dask benchmarks in notebooks
%%lbench - -dask - -rounds
3
my_collection.compute()
# With graph stats from a named variable:
%%lbench - -dask - -collection
src_catalog - -name
catalog_scan
src_catalog.compute()
Results within a notebook session are accumulated into a single timestamped run directory. Call
lbench.notebook.magic.reset_session() to start a fresh run directory mid-session.
Viewing Results with the Dashboard
lbench dash
lbench dash --port 8051
Or from a notebook:
from lbench.dashboard.app import run_dashboard
run_dashboard(port=8050)
Calling run_dashboard() again will restart the server on the new settings.
lbench dash and run_dashboard() use the Dash development server. To host the dashboard, point a WSGI
server at lbench.dashboard.app:server instead:
pip install gunicorn
LBENCH_ROOT=/path/to/results gunicorn --bind 0.0.0.0:8050 lbench.dashboard.app:server
Dashboard Features
Run browser (sidebar)
- Lists all runs in chronological order
- Filter runs by date range with the date picker
- Rename runs with the pencil icon (temporarily disabled for security)
Benchmark tables
- Per-benchmark cards showing timing stats, memory usage, and Dask metrics
- Links to open flamegraphs (cProfile) and Dask performance reports directly in the browser
Trend plots
- Click "Plot series" to switch to the trend view
- Select one or more benchmarks and a metric to plot performance over time
- Error bars show standard deviation where available
- Respects the active date filter
Example
import pytest
@pytest.mark.parametrize("size", [1000, 10000, 100000])
def test_dataframe_operation(size, lbench):
import pandas as pd
df = pd.DataFrame({'A': range(size), 'B': range(size)})
def benchmark_func():
result = df['A'] + df['B']
lbench(benchmark_func)
pytest --lbench tests/test_dataframe_operation.py
Metadata
Release files for lf-bench 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| lf_bench-0.2.0.tar.gz | 47.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lf_bench-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.1 kB
Release files / lf_bench-0.2.0.tar.gz
| Download URL | lf_bench-0.2.0.tar.gz |
|---|---|
| Size | 47.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
509f0548f50c4389881f6af095f1fcbf4f28a278d338aa6cfd644f1c509a2321
|
|
BLAKE2b-256 checksum How to use checksums |
23e7f3f8157144f85920ca032fa7b9714789c6750db03ef71bbc033d02fa725f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / lf_bench-0.2.0-py3-none-any.whl
| Download URL | lf_bench-0.2.0-py3-none-any.whl |
|---|---|
| Size | 34.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c872cf8461f65d324124b952a2ef7b12091ad0e9a93349a180c31a0648c2040
|
|
BLAKE2b-256 checksum How to use checksums |
dc4f874dabba3e947c9099259c475a5b59d6f24d15f74d1b722ca46db09f541e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for lf-bench 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for lf_bench-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.