Skip to content

Commit 48a4822

Browse files
toby-colemanadriencacciaclaude
authored
fix: Exclude setup time from benchmark in walltime mode (#114)
* Fix walltime mode * fix: fix ruff lint errors in walltime test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Adrien Cacciaguerra <adrien.caccia@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent aa267f3 commit 48a4822

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

src/pytest_codspeed/instruments/walltime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ def __codspeed_root_frame__(*args, **kwargs) -> T:
292292
if self.instrument_hooks:
293293
self.instrument_hooks.start_benchmark()
294294
for _ in range(pedantic_options.rounds):
295-
start = perf_counter_ns()
296295
args, kwargs = pedantic_options.setup_and_get_args_kwargs()
296+
start = perf_counter_ns()
297297
for _ in iter_range:
298298
__codspeed_root_frame__(*args, **kwargs)
299299
end = perf_counter_ns()

tests/test_pytest_plugin_walltime.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
import pytest
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
25
from conftest import run_pytest_codspeed_with_mode
36

7+
if TYPE_CHECKING:
8+
import pytest
9+
10+
from pytest_codspeed.config import (
11+
BenchmarkMarkerOptions,
12+
CodSpeedConfig,
13+
PedanticOptions,
14+
)
415
from pytest_codspeed.instruments import MeasurementMode
16+
from pytest_codspeed.instruments.walltime import WallTimeInstrument
517

618

719
def test_bench_enabled_header_with_perf(
@@ -86,3 +98,46 @@ def target(a, b, c):
8698
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
8799
assert result.ret == 0, "the run should have succeeded"
88100
result.assert_outcomes(passed=1)
101+
102+
103+
def test_benchmark_pedantic_walltime_setup_not_timed(monkeypatch: pytest.MonkeyPatch):
104+
"""Verify that the setup time is not included in the measurement
105+
when using pedantic mode with walltime."""
106+
current_time_ns = 0
107+
108+
def fake_perf_counter_ns() -> int:
109+
return current_time_ns
110+
111+
monkeypatch.setattr(
112+
"pytest_codspeed.instruments.walltime.perf_counter_ns", fake_perf_counter_ns
113+
)
114+
115+
def setup() -> tuple[tuple[int], dict[str, int]]:
116+
nonlocal current_time_ns
117+
current_time_ns += 200
118+
return (1,), {"c": 2}
119+
120+
def target(a: int, c: int) -> int:
121+
nonlocal current_time_ns
122+
current_time_ns += 400
123+
return a + c
124+
125+
instrument = WallTimeInstrument(CodSpeedConfig(), MeasurementMode.WallTime)
126+
result = instrument.measure_pedantic(
127+
BenchmarkMarkerOptions(),
128+
PedanticOptions(
129+
target=target,
130+
setup=setup,
131+
teardown=None,
132+
rounds=2,
133+
warmup_rounds=0,
134+
iterations=1,
135+
),
136+
name="test_pedantic_setup_not_timed",
137+
uri="tests/test_benchmark.py::test_pedantic_setup_not_timed",
138+
)
139+
140+
assert result == 3
141+
assert len(instrument.benchmarks) == 1
142+
# Two rounds should each measure target-only time (400ns), excluding setup (200ns).
143+
assert instrument.benchmarks[0].stats.min_ns == 400

0 commit comments

Comments
 (0)