pytest-codspeed 3.1.2__tar.gz → 3.2.0__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 (28) hide show
  1. {pytest_codspeed-3.1.2/src/pytest_codspeed.egg-info → pytest_codspeed-3.2.0}/PKG-INFO +1 -1
  2. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/pyproject.toml +7 -1
  3. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/__init__.py +2 -2
  4. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/walltime.py +21 -13
  5. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/plugin.py +2 -0
  6. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0/src/pytest_codspeed.egg-info}/PKG-INFO +1 -1
  7. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/LICENSE +0 -0
  8. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/README.md +0 -0
  9. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/setup.cfg +0 -0
  10. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/setup.py +0 -0
  11. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/__init__.py +0 -0
  12. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/__init__.py +0 -0
  13. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/_wrapper/__init__.py +0 -0
  14. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/_wrapper/build.py +0 -0
  15. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.c +0 -0
  16. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.h +0 -0
  17. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/instruments/valgrind/_wrapper/wrapper.pyi +0 -0
  18. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/py.typed +0 -0
  19. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed/utils.py +0 -0
  20. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed.egg-info/SOURCES.txt +0 -0
  21. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed.egg-info/dependency_links.txt +0 -0
  22. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed.egg-info/entry_points.txt +0 -0
  23. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed.egg-info/requires.txt +0 -0
  24. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/src/pytest_codspeed.egg-info/top_level.txt +0 -0
  25. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/tests/test_pytest_plugin.py +0 -0
  26. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/tests/test_pytest_plugin_cpu_instrumentation.py +0 -0
  27. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/tests/test_pytest_plugin_walltime.py +0 -0
  28. {pytest_codspeed-3.1.2 → pytest_codspeed-3.2.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytest-codspeed
3
- Version: 3.1.2
3
+ Version: 3.2.0
4
4
  Summary: Pytest plugin to create CodSpeed benchmarks
5
5
  Author-email: Arthur Pastel <arthur@codspeed.io>
6
6
  License: The MIT License (MIT)
@@ -45,6 +45,12 @@ compat = [
45
45
  ]
46
46
  test = ["pytest ~= 7.0", "pytest-cov ~= 4.0.0"]
47
47
 
48
+ [tool.uv.sources]
49
+ pytest-codspeed = { workspace = true }
50
+
51
+ [dependency-groups]
52
+ dev = ["pytest-codspeed"]
53
+
48
54
  [project.entry-points]
49
55
  pytest11 = { codspeed = "pytest_codspeed.plugin" }
50
56
 
@@ -60,7 +66,7 @@ version = { attr = "pytest_codspeed.__version__" }
60
66
 
61
67
 
62
68
  [tool.bumpver]
63
- current_version = "3.1.2"
69
+ current_version = "3.2.0"
64
70
  version_pattern = "MAJOR.MINOR.PATCH[-TAG[NUM]]"
65
71
  commit_message = "Release v{new_version} 🚀"
66
72
  tag_message = "Release v{new_version} 🚀"
@@ -1,6 +1,6 @@
1
- __version__ = "3.1.2"
1
+ __version__ = "3.2.0"
2
2
  # We also have the semver version since __version__ is not semver compliant
3
- __semver_version__ = "3.1.2"
3
+ __semver_version__ = "3.2.0"
4
4
 
5
5
  from .plugin import BenchmarkFixture
6
6
 
@@ -24,7 +24,10 @@ if TYPE_CHECKING:
24
24
  DEFAULT_WARMUP_TIME_NS = 1_000_000_000
25
25
  DEFAULT_MAX_TIME_NS = 3_000_000_000
26
26
  TIMER_RESOLUTION_NS = get_clock_info("perf_counter").resolution * 1e9
27
- DEFAULT_MIN_ROUND_TIME_NS = TIMER_RESOLUTION_NS * 100
27
+ DEFAULT_MIN_ROUND_TIME_NS = TIMER_RESOLUTION_NS * 1_000_000
28
+
29
+ IQR_OUTLIER_FACTOR = 1.5
30
+ STDEV_OUTLIER_FACTOR = 3
28
31
 
29
32
 
30
33
  @dataclass
@@ -69,13 +72,14 @@ class BenchmarkStats:
69
72
  @classmethod
70
73
  def from_list(
71
74
  cls,
72
- times_ns: list[float],
75
+ times_per_round_ns: list[float],
73
76
  *,
74
77
  rounds: int,
75
78
  iter_per_round: int,
76
79
  warmup_iters: int,
77
80
  total_time: float,
78
81
  ) -> BenchmarkStats:
82
+ times_ns = [t / iter_per_round for t in times_per_round_ns]
79
83
  stdev_ns = stdev(times_ns) if len(times_ns) > 1 else 0
80
84
  mean_ns = mean(times_ns)
81
85
  if len(times_ns) > 1:
@@ -88,12 +92,16 @@ class BenchmarkStats:
88
92
  )
89
93
  iqr_ns = q3_ns - q1_ns
90
94
  iqr_outlier_rounds = sum(
91
- 1 for t in times_ns if t < q1_ns - 1.5 * iqr_ns or t > q3_ns + 1.5 * iqr_ns
95
+ 1
96
+ for t in times_ns
97
+ if t < q1_ns - IQR_OUTLIER_FACTOR * iqr_ns
98
+ or t > q3_ns + IQR_OUTLIER_FACTOR * iqr_ns
92
99
  )
93
100
  stdev_outlier_rounds = sum(
94
101
  1
95
102
  for t in times_ns
96
- if t < mean_ns - 3 * stdev_ns or t > mean_ns + 3 * stdev_ns
103
+ if t < mean_ns - STDEV_OUTLIER_FACTOR * stdev_ns
104
+ or t > mean_ns + STDEV_OUTLIER_FACTOR * stdev_ns
97
105
  )
98
106
 
99
107
  return cls(
@@ -129,20 +137,20 @@ def run_benchmark(
129
137
  out = fn(*args, **kwargs)
130
138
 
131
139
  # Warmup
132
- times_ns: list[float] = []
140
+ times_per_round_ns: list[float] = []
133
141
  warmup_start = start = perf_counter_ns()
134
142
  while True:
135
143
  start = perf_counter_ns()
136
144
  fn(*args, **kwargs)
137
145
  end = perf_counter_ns()
138
- times_ns.append(end - start)
146
+ times_per_round_ns.append(end - start)
139
147
  if end - warmup_start > config.warmup_time_ns:
140
148
  break
141
149
 
142
150
  # Round sizing
143
- warmup_mean_ns = mean(times_ns)
144
- warmup_iters = len(times_ns)
145
- times_ns.clear()
151
+ warmup_mean_ns = mean(times_per_round_ns)
152
+ warmup_iters = len(times_per_round_ns)
153
+ times_per_round_ns.clear()
146
154
  iter_per_round = (
147
155
  int(ceil(config.min_round_time_ns / warmup_mean_ns))
148
156
  if warmup_mean_ns <= config.min_round_time_ns
@@ -163,7 +171,7 @@ def run_benchmark(
163
171
  for _ in iter_range:
164
172
  fn(*args, **kwargs)
165
173
  end = perf_counter_ns()
166
- times_ns.append(end - start)
174
+ times_per_round_ns.append(end - start)
167
175
 
168
176
  if end - run_start > config.max_time_ns:
169
177
  # TODO: log something
@@ -172,7 +180,7 @@ def run_benchmark(
172
180
  total_time = (benchmark_end - run_start) / 1e9
173
181
 
174
182
  stats = BenchmarkStats.from_list(
175
- times_ns,
183
+ times_per_round_ns,
176
184
  rounds=rounds,
177
185
  total_time=total_time,
178
186
  iter_per_round=iter_per_round,
@@ -240,12 +248,12 @@ class WallTimeInstrument(Instrument):
240
248
 
241
249
  for bench in self.benchmarks:
242
250
  rsd = bench.stats.stdev_ns / bench.stats.mean_ns
243
- rsd_text = Text(f"{rsd*100:.1f}%")
251
+ rsd_text = Text(f"{rsd * 100:.1f}%")
244
252
  if rsd > 0.1:
245
253
  rsd_text.stylize("red bold")
246
254
  table.add_row(
247
255
  escape(bench.name),
248
- f"{bench.stats.min_ns/bench.stats.iter_per_round:,.0f}ns",
256
+ f"{bench.stats.min_ns / bench.stats.iter_per_round:,.0f}ns",
249
257
  rsd_text,
250
258
  f"{bench.stats.total_time:,.2f}s",
251
259
  f"{bench.stats.iter_per_round * bench.stats.rounds:,}",
@@ -5,6 +5,7 @@ import gc
5
5
  import importlib.util
6
6
  import json
7
7
  import os
8
+ import random
8
9
  from dataclasses import dataclass, field
9
10
  from pathlib import Path
10
11
  from time import time
@@ -259,6 +260,7 @@ def _measure(
259
260
  *args: P.args,
260
261
  **kwargs: P.kwargs,
261
262
  ) -> T:
263
+ random.seed(0)
262
264
  is_gc_enabled = gc.isenabled()
263
265
  if is_gc_enabled:
264
266
  gc.collect()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytest-codspeed
3
- Version: 3.1.2
3
+ Version: 3.2.0
4
4
  Summary: Pytest plugin to create CodSpeed benchmarks
5
5
  Author-email: Arthur Pastel <arthur@codspeed.io>
6
6
  License: The MIT License (MIT)
File without changes