FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

test: use benchmark.pedantic for mark-to-expire benchmarks · python-zeroconf/python-zeroconf@bd36427 · GitHub

Commit bd36427

Browse files
committed
test: use benchmark.pedantic for mark-to-expire benchmarks
1 parent f6f4a8e commit bd36427

1 file changed

Lines changed: 71 additions & 70 deletions

File tree

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
"""Benchmarks for DNSCache.async_mark_unique_records_older_than_1s_to_expire.
22
3-
Covers the RFC 6762 §10.2 paragraph 2 path that marks superseded unique
4-
records to expire in 1s. Today it mutates cached records in place via
5-
``DNSRecord._set_created_ttl`` (see ``_cache.py`` line ~345). These
6-
benchmarks pin the cost of the current path so a copy-instead-of-mutate
7-
follow-up (issue #1780) has a baseline to compare against.
3+
Covers the RFC 6762 §10.2 paragraph 2 path. ``_async_set_created_ttl``
4+
mutates cached records in place, so a repeated-iteration benchmark
5+
would only measure work on the first call. Each test uses
6+
``benchmark.pedantic`` with a per-round ``setup`` that rebuilds the
7+
stale cache; the ``async_add_records`` cost stays outside the timed
8+
window.
89
"""
910

1011
from __future__ import annotations
1112

13+
from typing import Any
14+
1215
from pytest_codspeed import BenchmarkFixture
1316

1417
from zeroconf import DNSAddress, DNSCache, DNSPointer, current_time_millis
@@ -22,89 +25,69 @@ def _ipv4_bytes(i: int) -> bytes:
2225

2326

2427
def test_mark_to_expire_1000_records_all_stale(benchmark: BenchmarkFixture) -> None:
25-
"""Worst-case mark-to-expire: every cached record needs mutation.
26-
27-
1000 unique A records, all created > 1s ago, none in the new answer
28-
set — every iteration hits the ``_async_set_created_ttl`` path.
29-
"""
28+
"""Worst-case mark-to-expire: 1000 stale unique A records, all mutated."""
3029
now = current_time_millis()
3130
name = "stale.local."
32-
cache = DNSCache()
33-
cache.async_add_records(
34-
DNSAddress(
35-
name,
36-
_TYPE_A,
37-
_UNIQUE_CLASS,
38-
120,
39-
_ipv4_bytes(i),
40-
created=now - 5_000,
41-
)
42-
for i in range(1000)
43-
)
4431
unique_types = {(name, _TYPE_A, _UNIQUE_CLASS)}
45-
# An unrelated answer keeps every cached record in the "must expire"
32+
# Unrelated answer keeps every cached record in the "must expire"
4633
# branch (no membership hit short-circuits the mutation).
4734
answers = [DNSAddress(name, _TYPE_A, _UNIQUE_CLASS, 120, _ipv4_bytes(0xDEAD_BEEF))]
4835

49-
@benchmark
50-
def _mark() -> None:
36+
def _setup() -> tuple[tuple[Any, ...], dict[str, Any]]:
37+
cache = DNSCache()
38+
cache.async_add_records(
39+
DNSAddress(
40+
name,
41+
_TYPE_A,
42+
_UNIQUE_CLASS,
43+
120,
44+
_ipv4_bytes(i),
45+
created=now - 5_000,
46+
)
47+
for i in range(1000)
48+
)
49+
return (cache,), {}
50+
51+
def _mark(cache: DNSCache) -> None:
5152
cache.async_mark_unique_records_older_than_1s_to_expire(unique_types, answers, now)
5253

54+
benchmark.pedantic(_mark, setup=_setup)
5355

54-
def test_mark_to_expire_1000_records_none_stale(benchmark: BenchmarkFixture) -> None:
55-
"""Same shape, but every record is fresh (created < 1s ago).
5656

57-
Measures the scan + age-check overhead without paying any
58-
``_async_set_created_ttl`` cost. The delta to the all-stale case is
59-
the mutation+re-add tax we'd avoid by switching to copy-on-expire.
60-
"""
57+
def test_mark_to_expire_1000_records_none_stale(benchmark: BenchmarkFixture) -> None:
58+
"""Scan-only path: 1000 fresh records, no mutation."""
6159
now = current_time_millis()
6260
name = "fresh.local."
63-
cache = DNSCache()
64-
cache.async_add_records(
65-
DNSAddress(
66-
name,
67-
_TYPE_A,
68-
_UNIQUE_CLASS,
69-
120,
70-
_ipv4_bytes(i),
71-
created=now,
72-
)
73-
for i in range(1000)
74-
)
7561
unique_types = {(name, _TYPE_A, _UNIQUE_CLASS)}
7662
answers = [DNSAddress(name, _TYPE_A, _UNIQUE_CLASS, 120, _ipv4_bytes(0xDEAD_BEEF))]
7763

78-
@benchmark
79-
def _mark() -> None:
64+
def _setup() -> tuple[tuple[Any, ...], dict[str, Any]]:
65+
cache = DNSCache()
66+
cache.async_add_records(
67+
DNSAddress(
68+
name,
69+
_TYPE_A,
70+
_UNIQUE_CLASS,
71+
120,
72+
_ipv4_bytes(i),
73+
created=now,
74+
)
75+
for i in range(1000)
76+
)
77+
return (cache,), {}
78+
79+
def _mark(cache: DNSCache) -> None:
8080
cache.async_mark_unique_records_older_than_1s_to_expire(unique_types, answers, now)
8181

82+
benchmark.pedantic(_mark, setup=_setup)
8283

83-
def test_mark_to_expire_many_unique_types(benchmark: BenchmarkFixture) -> None:
84-
"""Many distinct (name, type, class) triplets, one stale record each.
8584

86-
Mirrors a burst response that supersedes 100 different unique RRsets
87-
in one packet — the outer loop dominates, but each inner iteration
88-
still triggers in-place mutation.
89-
"""
85+
def test_mark_to_expire_many_unique_types(benchmark: BenchmarkFixture) -> None:
86+
"""100 distinct (name, type, class) triplets, one stale record each."""
9087
now = current_time_millis()
91-
cache = DNSCache()
92-
unique_types: set[tuple[str, int, int]] = set()
93-
for i in range(100):
94-
name = f"svc{i}.local."
95-
cache.async_add_records(
96-
[
97-
DNSPointer(
98-
name,
99-
_TYPE_PTR,
100-
_UNIQUE_CLASS,
101-
120,
102-
f"target{i}.local.",
103-
created=now - 5_000,
104-
)
105-
]
106-
)
107-
unique_types.add((name, _TYPE_PTR, _UNIQUE_CLASS))
88+
unique_types: set[tuple[str, int, int]] = {
89+
(f"svc{i}.local.", _TYPE_PTR, _UNIQUE_CLASS) for i in range(100)
90+
}
10891
# New answers reference a different alias, so the cached entries are
10992
# not equal to anything in ``answers_rrset`` and must be expired.
11093
answers = [
@@ -118,6 +101,24 @@ def test_mark_to_expire_many_unique_types(benchmark: BenchmarkFixture) -> None:
118101
for i in range(100)
119102
]
120103

121-
@benchmark
122-
def _mark() -> None:
104+
def _setup() -> tuple[tuple[Any, ...], dict[str, Any]]:
105+
cache = DNSCache()
106+
for i in range(100):
107+
cache.async_add_records(
108+
[
109+
DNSPointer(
110+
f"svc{i}.local.",
111+
_TYPE_PTR,
112+
_UNIQUE_CLASS,
113+
120,
114+
f"target{i}.local.",
115+
created=now - 5_000,
116+
)
117+
]
118+
)
119+
return (cache,), {}
120+
121+
def _mark(cache: DNSCache) -> None:
123122
cache.async_mark_unique_records_older_than_1s_to_expire(unique_types, answers, now)
123+
124+
benchmark.pedantic(_mark, setup=_setup)

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL