"""Auto-generated example: Cache Patterns — run_tag and cache_samples."""
import math
import random
import bencher as bn
class NoisySensor(bn.ParametrizedSweep):
"""Simulates a sensor with configurable noise.
Demonstrates cache_samples and run_tag usage. When cache_samples is True,
each individual function call is cached so expensive computations are not
repeated if the run is interrupted.
"""
temperature = bn.FloatSweep(
default=25.0, bounds=[0.0, 100.0], doc="Sensor temperature", units="C"
)
reading = bn.ResultFloat(units="V", doc="Sensor voltage reading")
noise_scale = bn.FloatSweep(default=0.0, bounds=[0.0, 1.0], doc="Noise scale")
def benchmark(self):
self.reading = 0.5 + 0.03 * self.temperature + math.sin(self.temperature * 0.1)
if self.noise_scale > 0:
self.reading += random.gauss(0, self.noise_scale)
def example_advanced_cache_patterns(run_cfg: bn.BenchRunCfg | None = None) -> bn.Bench:
"""Cache Patterns — run_tag and cache_samples."""
run_cfg = bn.BenchRunCfg.with_defaults(run_cfg, repeats=5)
# run_tag partitions the cache so different experiment runs don't collide.
run_cfg.run_tag = "sensor_v1"
# cache_samples=True stores each individual call, useful for long-running
# benchmarks that might be interrupted.
run_cfg.cache_samples = True
run_cfg.clear_sample_cache = True
bench = NoisySensor().to_bench(run_cfg)
bench.plot_sweep(
input_vars=["temperature"],
result_vars=["reading"],
const_vars=dict(noise_scale=0.3),
description="Demonstrates cache_samples and run_tag for reliable benchmarking. "
"cache_samples=True stores every function call individually so data is not "
"lost if the run crashes. run_tag partitions the cache between experiments.",
post_description="The repeated measurements show noise around the true sensor "
"curve. If this run were interrupted, re-running would reuse cached samples.",
)
return bench
if __name__ == "__main__":
bn.run(example_advanced_cache_patterns, subsampling_divisions=3, repeats=5)