Skip to content

Commit c2a1644

Browse files
committed
feat: use instrument hooks
1 parent daa77c2 commit c2a1644

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

src/pytest_codspeed/instruments/valgrind.py

+11-14
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,33 @@
66

77
from pytest_codspeed import __semver_version__
88
from pytest_codspeed.instruments import Instrument
9-
from pytest_codspeed.instruments.valgrind._wrapper import get_lib
9+
from pytest_codspeed.instruments.hooks import InstrumentHooks
1010

1111
if TYPE_CHECKING:
1212
from typing import Any, Callable
1313

1414
from pytest import Session
1515

1616
from pytest_codspeed.instruments import P, T
17-
from pytest_codspeed.instruments.valgrind._wrapper import LibType
1817
from pytest_codspeed.plugin import CodSpeedConfig
1918

2019
SUPPORTS_PERF_TRAMPOLINE = sys.version_info >= (3, 12)
2120

2221

2322
class ValgrindInstrument(Instrument):
2423
instrument = "valgrind"
25-
lib: LibType | None
24+
instrument_hooks: InstrumentHooks
2625

2726
def __init__(self, config: CodSpeedConfig) -> None:
27+
self.instrument_hooks = InstrumentHooks()
28+
2829
self.benchmark_count = 0
2930
self.should_measure = os.environ.get("CODSPEED_ENV") is not None
3031
if self.should_measure:
31-
self.lib = get_lib()
32-
self.lib.dump_stats_at(
33-
f"Metadata: pytest-codspeed {__semver_version__}".encode("ascii")
34-
)
32+
self.instrument_hooks.set_integration("pytest-codspeed", __semver_version__)
33+
3534
if SUPPORTS_PERF_TRAMPOLINE:
3635
sys.activate_stack_trampoline("perf") # type: ignore
37-
else:
38-
self.lib = None
3936

4037
def get_instrument_config_str_and_warns(self) -> tuple[str, list[str]]:
4138
config = (
@@ -61,7 +58,8 @@ def measure(
6158
**kwargs: P.kwargs,
6259
) -> T:
6360
self.benchmark_count += 1
64-
if self.lib is None: # Thus should_measure is False
61+
62+
if not self.should_measure:
6563
return fn(*args, **kwargs)
6664

6765
def __codspeed_root_frame__() -> T:
@@ -71,14 +69,13 @@ def __codspeed_root_frame__() -> T:
7169
# Warmup CPython performance map cache
7270
__codspeed_root_frame__()
7371

74-
self.lib.zero_stats()
75-
self.lib.start_instrumentation()
72+
self.instrument_hooks.start_benchmark()
7673
try:
7774
return __codspeed_root_frame__()
7875
finally:
7976
# Ensure instrumentation is stopped even if the test failed
80-
self.lib.stop_instrumentation()
81-
self.lib.dump_stats_at(uri.encode("ascii"))
77+
self.instrument_hooks.stop_benchmark()
78+
self.instrument_hooks.set_current_benchmark(uri)
8279

8380
def report(self, session: Session) -> None:
8481
reporter = session.config.pluginmanager.get_plugin("terminalreporter")

src/pytest_codspeed/instruments/walltime.py

+26-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import sys
34
from dataclasses import asdict, dataclass
45
from math import ceil
56
from statistics import mean, quantiles, stdev
@@ -11,7 +12,9 @@
1112
from rich.table import Table
1213
from rich.text import Text
1314

15+
from pytest_codspeed import __semver_version__
1416
from pytest_codspeed.instruments import Instrument
17+
from pytest_codspeed.instruments.hooks import InstrumentHooks
1518

1619
if TYPE_CHECKING:
1720
from typing import Any, Callable
@@ -131,17 +134,26 @@ class Benchmark:
131134

132135

133136
def run_benchmark(
134-
name: str, uri: str, fn: Callable[P, T], args, kwargs, config: BenchmarkConfig
137+
instrument_hooks: InstrumentHooks,
138+
name: str,
139+
uri: str,
140+
fn: Callable[P, T],
141+
args,
142+
kwargs,
143+
config: BenchmarkConfig,
135144
) -> tuple[Benchmark, T]:
145+
def __codspeed_root_frame__() -> T:
146+
return fn(*args, **kwargs)
147+
136148
# Compute the actual result of the function
137-
out = fn(*args, **kwargs)
149+
out = __codspeed_root_frame__()
138150

139151
# Warmup
140152
times_per_round_ns: list[float] = []
141153
warmup_start = start = perf_counter_ns()
142154
while True:
143155
start = perf_counter_ns()
144-
fn(*args, **kwargs)
156+
__codspeed_root_frame__()
145157
end = perf_counter_ns()
146158
times_per_round_ns.append(end - start)
147159
if end - warmup_start > config.warmup_time_ns:
@@ -166,16 +178,19 @@ def run_benchmark(
166178
# Benchmark
167179
iter_range = range(iter_per_round)
168180
run_start = perf_counter_ns()
181+
instrument_hooks.start_benchmark()
169182
for _ in range(rounds):
170183
start = perf_counter_ns()
171184
for _ in iter_range:
172-
fn(*args, **kwargs)
185+
__codspeed_root_frame__()
173186
end = perf_counter_ns()
174187
times_per_round_ns.append(end - start)
175188

176189
if end - run_start > config.max_time_ns:
177190
# TODO: log something
178191
break
192+
instrument_hooks.stop_benchmark()
193+
instrument_hooks.set_current_benchmark(uri)
179194
benchmark_end = perf_counter_ns()
180195
total_time = (benchmark_end - run_start) / 1e9
181196

@@ -192,10 +207,16 @@ def run_benchmark(
192207

193208
class WallTimeInstrument(Instrument):
194209
instrument = "walltime"
210+
instrument_hooks: InstrumentHooks
195211

196212
def __init__(self, config: CodSpeedConfig) -> None:
213+
self.instrument_hooks = InstrumentHooks()
214+
197215
self.config = config
198216
self.benchmarks: list[Benchmark] = []
217+
sys.activate_stack_trampoline("perf") # type: ignore
218+
219+
self.instrument_hooks.set_integration("pytest-codspeed", __semver_version__)
199220

200221
def get_instrument_config_str_and_warns(self) -> tuple[str, list[str]]:
201222
return f"mode: walltime, timer_resolution: {TIMER_RESOLUTION_NS:.1f}ns", []
@@ -209,6 +230,7 @@ def measure(
209230
**kwargs: P.kwargs,
210231
) -> T:
211232
bench, out = run_benchmark(
233+
instrument_hooks=self.instrument_hooks,
212234
name=name,
213235
uri=uri,
214236
fn=fn,

0 commit comments

Comments
 (0)