11from __future__ import annotations
22
3+ import sys
34from dataclasses import asdict , dataclass
45from math import ceil
56from statistics import mean , quantiles , stdev
1112from rich .table import Table
1213from rich .text import Text
1314
15+ from pytest_codspeed import __semver_version__
1416from pytest_codspeed .instruments import Instrument
17+ from pytest_codspeed .instruments .hooks import InstrumentHooks
1518
1619if TYPE_CHECKING :
1720 from typing import Any , Callable
@@ -131,17 +134,26 @@ class Benchmark:
131134
132135
133136def 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
193208class 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