pytest-codspeed 3.0.0b1__tar.gz → 3.0.0b3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (16) hide show
  1. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/PKG-INFO +1 -1
  2. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/__init__.py +2 -2
  3. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/walltime.py +26 -6
  4. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/plugin.py +18 -3
  5. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/.gitignore +0 -0
  6. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/LICENSE +0 -0
  7. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/README.md +0 -0
  8. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/pyproject.toml +0 -0
  9. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/__init__.py +0 -0
  10. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/__init__.py +0 -0
  11. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/_wrapper/.gitignore +0 -0
  12. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/_wrapper/__init__.py +0 -0
  13. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.c +0 -0
  14. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.h +0 -0
  15. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.pyi +0 -0
  16. {pytest_codspeed-3.0.0b1 → pytest_codspeed-3.0.0b3}/src/pytest_codspeed/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pytest-codspeed
3
- Version: 3.0.0b1
3
+ Version: 3.0.0b3
4
4
  Summary: Pytest plugin to create CodSpeed benchmarks
5
5
  Project-URL: Homepage, https://codspeed.io/
6
6
  Project-URL: Documentation, https://docs.codspeed.io/
@@ -1,6 +1,6 @@
1
- __version__ = "3.0.0b1"
1
+ __version__ = "3.0.0b3"
2
2
  # We also have the semver version since __version__ is not semver compliant
3
- __semver_version__ = "3.0.0-b1"
3
+ __semver_version__ = "3.0.0-b3"
4
4
 
5
5
  from .plugin import BenchmarkFixture
6
6
 
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import asdict, dataclass
4
4
  from math import ceil
5
- from statistics import mean, median, stdev
5
+ from statistics import mean, quantiles, stdev
6
6
  from time import get_clock_info, perf_counter_ns
7
7
  from typing import TYPE_CHECKING
8
8
 
@@ -40,8 +40,10 @@ class BenchmarkConfig:
40
40
  if config.warmup_time_ns is not None
41
41
  else DEFAULT_WARMUP_TIME_NS,
42
42
  min_round_time_ns=DEFAULT_MIN_ROUND_TIME_NS,
43
- max_time_ns=DEFAULT_MAX_TIME_NS,
44
- max_rounds=config.max_rounds or None,
43
+ max_time_ns=config.max_time_ns
44
+ if config.max_time_ns is not None
45
+ else DEFAULT_MAX_TIME_NS,
46
+ max_rounds=config.max_rounds,
45
47
  )
46
48
 
47
49
 
@@ -49,9 +51,14 @@ class BenchmarkConfig:
49
51
  class BenchmarkStats:
50
52
  min_ns: float
51
53
  max_ns: float
52
- stdev_ns: float
53
54
  mean_ns: float
55
+ stdev_ns: float
56
+
57
+ lower_fence_ns: float
58
+ q1_ns: float
54
59
  median_ns: float
60
+ q3_ns: float
61
+ upper_fence_ns: float
55
62
 
56
63
  rounds: int
57
64
  total_time: float
@@ -71,15 +78,27 @@ class BenchmarkStats:
71
78
  ) -> BenchmarkStats:
72
79
  stdev_ns = stdev(times_ns) if len(times_ns) > 1 else 0
73
80
  mean_ns = mean(times_ns)
81
+ q1_ns, median_ns, q3_ns = quantiles(times_ns, n=4)
82
+ iqr_ns = q3_ns - q1_ns
83
+ lower_fence_ns = q1_ns - 1.5 * iqr_ns
84
+ upper_fence_ns = q3_ns + 1.5 * iqr_ns
85
+ outliers_rounds = sum(
86
+ 1 for t in times_ns if t < lower_fence_ns or t > upper_fence_ns
87
+ )
88
+
74
89
  return cls(
75
90
  min_ns=min(times_ns),
76
91
  max_ns=max(times_ns),
77
92
  stdev_ns=stdev_ns,
78
93
  mean_ns=mean_ns,
79
- median_ns=median(times_ns),
94
+ lower_fence_ns=lower_fence_ns,
95
+ q1_ns=q1_ns,
96
+ median_ns=median_ns,
97
+ q3_ns=q3_ns,
98
+ upper_fence_ns=upper_fence_ns,
80
99
  rounds=rounds,
81
100
  total_time=total_time,
82
- outlier_rounds=sum(1 for t in times_ns if abs(t - mean_ns) > stdev_ns),
101
+ outlier_rounds=outliers_rounds,
83
102
  iter_per_round=iter_per_round,
84
103
  warmup_iters=warmup_iters,
85
104
  )
@@ -125,6 +144,7 @@ def run_benchmark(
125
144
  rounds = int(config.max_time_ns / round_time_ns)
126
145
  else:
127
146
  rounds = config.max_rounds
147
+ rounds = max(1, rounds)
128
148
 
129
149
  # Benchmark
130
150
  iter_range = range(iter_per_round)
@@ -61,6 +61,15 @@ def pytest_addoption(parser: pytest.Parser):
61
61
  "only for walltime mode"
62
62
  ),
63
63
  )
64
+ group.addoption(
65
+ "--codspeed-max-time",
66
+ action="store",
67
+ type=float,
68
+ help=(
69
+ "The maximum time to run a benchmark for (in seconds), "
70
+ "only for walltime mode"
71
+ ),
72
+ )
64
73
  group.addoption(
65
74
  "--codspeed-max-rounds",
66
75
  action="store",
@@ -75,6 +84,7 @@ def pytest_addoption(parser: pytest.Parser):
75
84
  @dataclass(frozen=True)
76
85
  class CodSpeedConfig:
77
86
  warmup_time_ns: int | None = None
87
+ max_time_ns: int | None = None
78
88
  max_rounds: int | None = None
79
89
 
80
90
  @classmethod
@@ -83,9 +93,12 @@ class CodSpeedConfig:
83
93
  warmup_time_ns = (
84
94
  int(warmup_time * 1_000_000_000) if warmup_time is not None else None
85
95
  )
96
+ max_time = config.getoption("--codspeed-max-time", None)
97
+ max_time_ns = int(max_time * 1_000_000_000) if max_time is not None else None
86
98
  return cls(
87
99
  warmup_time_ns=warmup_time_ns,
88
100
  max_rounds=config.getoption("--codspeed-max-rounds", None),
101
+ max_time_ns=max_time_ns,
89
102
  )
90
103
 
91
104
 
@@ -248,15 +261,17 @@ def _measure(
248
261
  ) -> T:
249
262
  is_gc_enabled = gc.isenabled()
250
263
  if is_gc_enabled:
251
- gc.collect()
252
- gc.disable()
264
+ pass
265
+ # gc.collect()
266
+ # gc.disable()
253
267
  try:
254
268
  uri, name = get_git_relative_uri_and_name(nodeid, config.rootpath)
255
269
  return plugin.instrument.measure(name, uri, fn, *args, **kwargs)
256
270
  finally:
257
271
  # Ensure GC is re-enabled even if the test failed
258
272
  if is_gc_enabled:
259
- gc.enable()
273
+ pass
274
+ # gc.enable()
260
275
 
261
276
 
262
277
  def wrap_runtest(