-
Notifications
You must be signed in to change notification settings - Fork 427
/
Copy path_scenario.py
72 lines (53 loc) · 2 KB
/
_scenario.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import abc
import dataclasses
import time
def str_to_bool(_input):
return _input in (True, "True", "true", "Yes", "yes", "Y", "y", "On", "on", "1", 1)
def _register(scenario_cls):
"""Registers a scenario for benchmarking."""
import pyperf
# This extends pyperf's runner by registering arguments for the scenario config
def add_cmdline_args(cmd, args):
for _field in dataclasses.fields(scenario_cls):
if hasattr(args, _field.name):
cmd.extend(("--{}".format(_field.name), str(getattr(args, _field.name))))
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args)
cmd = runner.argparser
for _field in dataclasses.fields(scenario_cls):
cmd.add_argument("--{}".format(_field.name), type=_field.type if _field.type is not bool else str_to_bool)
parsed_args = runner.parse_args()
config_dict = {
_field.name: getattr(parsed_args, _field.name)
for _field in dataclasses.fields(scenario_cls)
if hasattr(parsed_args, _field.name)
}
scenario = scenario_cls(**config_dict)
runner.bench_time_func(scenario.scenario_name, scenario._pyperf)
@dataclasses.dataclass
class Scenario:
"""The base class for specifying a benchmark."""
name: str
def __init_subclass__(cls, **kwargs) -> None:
super().__init_subclass__(**kwargs)
dataclasses.dataclass(cls)
_register(cls)
@property
def scenario_name(self):
return "{}-{}".format(self.__class__.__name__.lower(), self.name)
@abc.abstractmethod
def run(self):
"""Returns a context manager that yields a function to be run for performance testing."""
pass
def _pyperf(self, loops):
rungen = self.run()
run = next(rungen)
t0 = time.perf_counter()
run(loops)
dt = time.perf_counter() - t0
try:
# perform any teardown
next(rungen)
except StopIteration:
pass
finally:
return dt # noqa: B012