/
/
/
1"""
2Benchmarks for hot-path string/parsing helpers.
3
4These helpers run on every media item during library sync, matching and metadata
5parsing, so they sit squarely on the performance-critical path. They are pure,
6CPU-bound functions, which makes them a good fit for CodSpeed's deterministic
7simulation instrument.
8"""
9
10from __future__ import annotations
11
12from typing import TYPE_CHECKING
13
14from music_assistant.helpers.compare import (
15 compare_strings,
16 compare_version,
17 create_safe_string,
18 loose_compare_strings,
19)
20from music_assistant.helpers.json import json_dumps, json_loads
21from music_assistant.helpers.util import (
22 clean_stream_title,
23 parse_title_and_version,
24 sanitize_http_header_value,
25)
26
27if TYPE_CHECKING:
28 from pytest_codspeed import BenchmarkFixture
29
30# A representative mix of real-world track/album titles as they arrive from
31# streaming providers: plain titles, featurings, remaster suffixes, bracketed
32# version info and accented / non-ASCII characters.
33SAMPLE_TITLES = [
34 "Bohemian Rhapsody",
35 "Blinding Lights (Official Music Video)",
36 "Smells Like Teen Spirit - Remastered 2021",
37 "One More Time (feat. Romanthony)",
38 "Björk - Jóga",
39 "Take On Me [Extended Version]",
40 "Stairway to Heaven (Live at MSG)",
41 "Get Lucky (Radio Edit) [feat. Pharrell Williams]",
42 "Numb / Encore",
43 "SÃ, señor - Acoustic",
44]
45
46SAMPLE_VERSIONS = [
47 ("Remastered 2011", "2011 Remaster"),
48 ("Deluxe Edition", "Deluxe"),
49 ("", "original soundtrack"),
50 ("Radio Edit", "radio version"),
51 ("Live", "Live Version"),
52]
53
54SAMPLE_STREAM_TITLES = [
55 "StreamTitle='AC/DC - Thunderstruck';StreamUrl='';",
56 'text="Daft Punk - Around the World" song_spot="M"',
57 "The Beatles - Here Comes the Sun",
58 'title="Adele - Hello" artist="Adele"',
59 "Now playing: Coldplay - Yellow on Radio X - advert.com",
60]
61
62
63def test_compare_strings_strict(benchmark: BenchmarkFixture) -> None:
64 """Exact (strict) string comparison across the sample title set."""
65
66 def run() -> int:
67 matches = 0
68 for base in SAMPLE_TITLES:
69 for alt in SAMPLE_TITLES:
70 if compare_strings(base, alt, strict=True):
71 matches += 1
72 return matches
73
74 benchmark(run)
75
76
77def test_compare_strings_fuzzy(benchmark: BenchmarkFixture) -> None:
78 """Fuzzy string comparison (difflib path) across the sample title set."""
79
80 def run() -> int:
81 matches = 0
82 for base in SAMPLE_TITLES:
83 for alt in SAMPLE_TITLES:
84 if compare_strings(base, alt, strict=False):
85 matches += 1
86 return matches
87
88 benchmark(run)
89
90
91def test_create_safe_string(benchmark: BenchmarkFixture) -> None:
92 """Unicode normalization + regex cleanup used before every compare."""
93
94 def run() -> list[str]:
95 return [create_safe_string(title) for title in SAMPLE_TITLES]
96
97 benchmark(run)
98
99
100def test_loose_compare_strings(benchmark: BenchmarkFixture) -> None:
101 """Partial-match comparison used to group versions of the same item."""
102
103 def run() -> int:
104 matches = 0
105 for base in SAMPLE_TITLES:
106 for alt in SAMPLE_TITLES:
107 if loose_compare_strings(base, alt):
108 matches += 1
109 return matches
110
111 benchmark(run)
112
113
114def test_compare_version(benchmark: BenchmarkFixture) -> None:
115 """Version string comparison across a mix of representative pairs."""
116
117 def run() -> int:
118 return sum(compare_version(base, alt) for base, alt in SAMPLE_VERSIONS)
119
120 benchmark(run)
121
122
123def test_parse_title_and_version(benchmark: BenchmarkFixture) -> None:
124 """Standard title/version splitting run on every parsed media item."""
125
126 def run() -> list[tuple[str, str]]:
127 return [parse_title_and_version(title) for title in SAMPLE_TITLES]
128
129 benchmark(run)
130
131
132def test_parse_title_and_version_for_search(benchmark: BenchmarkFixture) -> None:
133 """Aggressive title stripping used to build search queries."""
134
135 def run() -> list[tuple[str, str]]:
136 return [parse_title_and_version(title, strip_for_search=True) for title in SAMPLE_TITLES]
137
138 benchmark(run)
139
140
141def test_clean_stream_title(benchmark: BenchmarkFixture) -> None:
142 """Radio StreamTitle parsing, executed for every ICY metadata update."""
143
144 def run() -> list[str]:
145 return [clean_stream_title(line) for line in SAMPLE_STREAM_TITLES]
146
147 benchmark(run)
148
149
150def test_sanitize_http_header_value(benchmark: BenchmarkFixture) -> None:
151 """Header sanitization applied to track metadata on every stream request."""
152
153 def run() -> list[str]:
154 return [sanitize_http_header_value(title) for title in SAMPLE_TITLES]
155
156 benchmark(run)
157
158
159def test_json_dumps(benchmark: BenchmarkFixture) -> None:
160 """orjson-backed serialization used across the API and cache layers."""
161 payload = {
162 "items": [
163 {
164 "item_id": str(idx),
165 "name": title,
166 "provider": "spotify",
167 "media_type": "track",
168 "duration": 180 + idx,
169 "artists": ["Some Artist", "Another Artist"],
170 "metadata": {"explicit": bool(idx % 2), "popularity": idx * 3},
171 }
172 for idx, title in enumerate(SAMPLE_TITLES)
173 ]
174 }
175
176 benchmark(lambda: json_dumps(payload))
177
178
179def test_json_loads(benchmark: BenchmarkFixture) -> None:
180 """orjson-backed deserialization of a representative API payload."""
181 payload = {
182 "items": [
183 {
184 "item_id": str(idx),
185 "name": title,
186 "provider": "spotify",
187 "media_type": "track",
188 "duration": 180 + idx,
189 }
190 for idx, title in enumerate(SAMPLE_TITLES)
191 ]
192 }
193 raw = json_dumps(payload)
194
195 benchmark(lambda: json_loads(raw))
196