Skip to content

Commit d1342cf

Browse files
perf: Auto-register bm.Scenario sub-classes (#2791)
* perf: Auto-register bm.Scenario sub-classes * fix syntax error * do not shadow dict Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent e2e20aa commit d1342cf

File tree

8 files changed

+40
-43
lines changed

8 files changed

+40
-43
lines changed

benchmarks/README.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ A scenario requires:
1414
* ``config.yaml``: specifies one or more sets of configuration variables for the benchmark
1515
* ``requirements_scenario.txt``: any additional dependencies
1616

17-
The scenario class inherits from ``bm.Scenario`` and includes the configurable variables using ``bm.var``. The execution of the benchmark uses the ``run()`` generator function to yield a function that will handle the execution of a specified number of loops. The scenario class must also be decorated with ``@bm.register`` to ensure that it is run.
17+
The scenario class inherits from ``bm.Scenario`` and includes the configurable variables using ``bm.var``. The execution of the benchmark uses the ``run()`` generator function to yield a function that will handle the execution of a specified number of loops.
1818

1919
Example
2020
~~~~~~~
@@ -27,7 +27,6 @@ Example
2727
import bm
2828

2929

30-
@bm.register
3130
class MyScenario(bm.Scenario):
3231
size = bm.var(type=int)
3332

benchmarks/bm/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from ._scenario import Scenario
2-
from ._scenario import register
32
from ._scenario import var
43

54

65
__all__ = [
7-
"register",
86
"var",
97
"Scenario",
108
]

benchmarks/bm/_scenario.py

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,49 @@
66
import six
77

88

9-
def register(cls):
10-
"""Decorator for scenario class that registers the scenario to be run."""
11-
wrapped_cls = attr.s(cls)
12-
_register(wrapped_cls)
13-
return wrapped_cls
9+
var = attr.ib
1410

1511

16-
var = attr.ib
12+
def _register(scenario_cls):
13+
"""Registers a scenario for benchmarking."""
14+
# This extends pyperf's runner by registering arguments for the scenario config
15+
def add_cmdline_args(cmd, args):
16+
for field in attr.fields(scenario_cls):
17+
if hasattr(args, field.name):
18+
cmd.extend(("--{}".format(field.name), str(getattr(args, field.name))))
19+
20+
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args)
21+
cmd = runner.argparser
22+
23+
for field in attr.fields(scenario_cls):
24+
cmd.add_argument("--{}".format(field.name), type=field.type)
25+
26+
parsed_args = runner.parse_args()
27+
28+
config_dict = {
29+
field.name: getattr(parsed_args, field.name)
30+
for field in attr.fields(scenario_cls)
31+
if hasattr(parsed_args, field.name)
32+
}
33+
scenario = scenario_cls(**config_dict)
34+
35+
runner.bench_time_func(scenario.scenario_name, scenario._pyperf)
36+
37+
38+
class ScenarioMeta(abc.ABCMeta):
39+
def __init__(cls, name, bases, _dict):
40+
super(ScenarioMeta, cls).__init__(name, bases, _dict)
1741

42+
# Make sure every sub-class is wrapped by `attr.s`
43+
cls = attr.s()(cls)
1844

19-
@attr.s
20-
class Scenario(six.with_metaclass(abc.ABCMeta)):
45+
# Do not register the base Scenario class
46+
# DEV: We cannot compare `cls` to `Scenario` since it doesn't exist yet
47+
if cls.__module__ != __name__:
48+
_register(cls)
49+
50+
51+
class Scenario(six.with_metaclass(ScenarioMeta)):
2152
"""The base class for specifying a benchmark."""
2253

2354
name = attr.ib(type=str)
@@ -44,29 +75,3 @@ def _pyperf(self, loops):
4475
pass
4576
finally:
4677
return dt
47-
48-
49-
def _register(scenario_cls):
50-
"""Registers a scenario for benchmarking."""
51-
# This extends pyperf's runner by registering arguments for the scenario config
52-
def add_cmdline_args(cmd, args):
53-
for field in attr.fields(scenario_cls):
54-
if hasattr(args, field.name):
55-
cmd.extend(("--{}".format(field.name), str(getattr(args, field.name))))
56-
57-
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args)
58-
cmd = runner.argparser
59-
60-
for field in attr.fields(scenario_cls):
61-
cmd.add_argument("--{}".format(field.name), type=field.type)
62-
63-
parsed_args = runner.parse_args()
64-
65-
config_dict = {
66-
field.name: getattr(parsed_args, field.name)
67-
for field in attr.fields(scenario_cls)
68-
if hasattr(parsed_args, field.name)
69-
}
70-
scenario = scenario_cls(**config_dict)
71-
72-
runner.bench_time_func(scenario.scenario_name, scenario._pyperf)

benchmarks/django_simple/scenario.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import utils
33

44

5-
@bm.register
65
class DjangoSimple(bm.Scenario):
76
tracer_enabled = bm.var(type=bool)
87
profiler_enabled = bm.var(type=bool)

benchmarks/encoder/scenario.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import utils
33

44

5-
@bm.register
65
class Encoder(bm.Scenario):
76
ntraces = bm.var(type=int)
87
nspans = bm.var(type=int)

benchmarks/flask_simple/scenario.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import utils
33

44

5-
@bm.register
65
class FlaskSimple(bm.Scenario):
76
tracer_enabled = bm.var(type=bool)
87
profiler_enabled = bm.var(type=bool)

benchmarks/span/scenario.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from ddtrace import Span as dd_Span
55

66

7-
@bm.register
87
class Span(bm.Scenario):
98
nspans = bm.var(type=int)
109
ntags = bm.var(type=int)

benchmarks/tracer/scenario.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ def process_trace(self, trace):
88
return
99

1010

11-
@bm.register
1211
class Tracer(bm.Scenario):
1312
depth = bm.var(type=int)
1413

0 commit comments

Comments
 (0)