cs_survival_kit.bench.core ¶
The timing harness: define cases, time them, and fit their growth.
MIN_MEASUREMENT_NS
module-attribute
¶
A measurement loops its case until the timed calls add up to this long.
Fit
dataclass
¶
CaseResult
dataclass
¶
The measurements for one case of a benchmark.
Attributes:
| Name | Type | Description |
|---|---|---|
label |
str
|
The case's label. |
status |
str
|
|
sizes |
list[int]
|
The input sizes that were measured. |
seconds |
list[float]
|
Per-call time for each entry of |
slope |
float | None
|
Log-log slope of |
Results
dataclass
¶
Results(name: str, run_at: str, package_version: str, environment: dict[str, str], cases: list[CaseResult], per_item: bool = False)
The outcome of one Benchmark.run.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The benchmark's name. |
run_at |
str
|
When the run started, as an ISO 8601 UTC timestamp. |
package_version |
str
|
The |
environment |
dict[str, str]
|
The interpreter and machine the run happened on. |
cases |
list[CaseResult]
|
One result per case, in the order the cases were added. |
per_item |
bool
|
Whether a run of size |
fit ¶
Estimate each case's growth from its measurements.
The slope of time against size on a log-log scale approximates the
exponent k in O(n^k): about 0 is constant, about 1 is linear,
about 2 is quadratic. O(n log n) has no exponent of its own and
reads as slightly above 1.
This is an empirical sanity check, not a proof. Constant factors, caches and small sizes all bend the line.
Returns:
| Type | Description |
|---|---|
dict[str, Fit]
|
A mapping from case label to its fit. |
Source code in lib/cs_survival_kit/bench/core.py
format ¶
Render the results as a plain-text table.
Returns:
| Type | Description |
|---|---|
str
|
One row per size and one column per case, followed by each |
str
|
case's slope and growth. For a |
str
|
table follows with every time divided by its size: the amortized |
str
|
cost of one operation. A flat column there means constant cost |
str
|
per operation; a growing one means each operation gets more |
str
|
expensive as the input grows. |
Source code in lib/cs_survival_kit/bench/core.py
table ¶
Benchmark ¶
A named set of cases, each timed across a range of input sizes.
Each case pairs a setup function, which builds the inputs for a size
and is not timed, with a run function, which is. Cases in the same
benchmark are alternatives to compare, such as two implementations of one
operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A unique name for the benchmark, such as
|
required |
sizes
|
Sequence[int]
|
The input sizes to measure. Cases use these unless they bring their own. |
required |
per_item
|
bool
|
Set this when a run of size |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> b = Benchmark("sum", sizes=[1_000, 10_000])
>>> b.case("builtin", setup=lambda n: list(range(n)), run=sum)
>>> results = b.run(smoke=True)
>>> [case.sizes for case in results.cases]
[[1000]]
- Reference (cs-survival-kit 0.6.0) cs_survival_kit bench
- Reference (cs-survival-kit 0.6.0) cs_survival_kit bench cli load_benchmarks
Source code in lib/cs_survival_kit/bench/core.py
case ¶
case(label: str, *, setup: Callable[[int], T], run: Callable[[T], object], sizes: Sequence[int] | None = None) -> None
Add a case to the benchmark.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
A name for the case, unique within the benchmark. |
required |
setup
|
Callable[[int], T]
|
Builds the inputs for a size |
required |
run
|
Callable[[T], object]
|
The code to time. It receives whatever |
required |
sizes
|
Sequence[int] | None
|
Sizes for this case only, overriding the benchmark's. Use it to cap a slow case at smaller inputs. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in lib/cs_survival_kit/bench/core.py
run ¶
Time every case at every size.
Each measurement calls run in a loop until the timed calls add up
to about 0.1 seconds, so that fast calls are not lost in timer noise.
The reported time is per call, and is the minimum over repeat
measurements: the minimum is the run least disturbed by the rest of
the machine. Garbage collection is disabled while timing.
A case that raises NotImplementedError is reported as
"not implemented" and skipped, so benchmarks can be written before
the code they measure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repeat
|
int
|
How many measurements to take per size. |
5
|
smoke
|
bool
|
Only check that the cases execute: time the smallest size once, with a single call. The numbers are meaningless. |
False
|
Returns:
| Type | Description |
|---|---|
Results
|
The measurements for every case. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
- Reference (cs-survival-kit 0.6.0) cs_survival_kit bench
Source code in lib/cs_survival_kit/bench/core.py
fit_slope ¶
Fit the log-log slope of time against size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sizes
|
Sequence[int]
|
The input sizes. |
required |
seconds
|
Sequence[float]
|
The time measured at each size. |
required |
Returns:
| Type | Description |
|---|---|
float | None
|
The least-squares slope of |
float | None
|
|
- Reference (cs-survival-kit 0.6.0) cs_survival_kit bench core describe_slope
Source code in lib/cs_survival_kit/bench/core.py
describe_slope ¶
Give a rough human-readable reading of a log-log slope.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slope
|
float
|
A slope from |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
str
|
within 0.25 of 0, 1 or 2, and a looser description otherwise. Note |
str
|
that |