@@ -63,6 +63,7 @@ cmake --build _build
6363Key build options:
6464- ` skyr_BUILD_TESTS ` (ON): Build tests
6565- ` skyr_BUILD_WPT ` (OFF): Build Web Platform Tests runner
66+ - ` skyr_BUILD_BENCHMARKS ` (OFF): Build performance benchmarks
6667- ` skyr_ENABLE_FILESYSTEM_FUNCTIONS ` (ON): Enable filesystem::path conversion
6768- ` skyr_ENABLE_JSON_FUNCTIONS ` (ON): Enable JSON serialization
6869- ` skyr_BUILD_WITHOUT_EXCEPTIONS ` (OFF): Build without exceptions
@@ -221,6 +222,138 @@ Test data comes from the official WPT repository:
221222
222223This ensures compliance testing against the latest WhatWG URL specification test cases.
223224
225+ ## Benchmarks
226+
227+ ** Performance benchmarks** measure runtime URL parsing speed to identify optimization opportunities and track performance regressions.
228+
229+ ### Philosophy
230+
231+ - ** Measure, don't guess** - Profile before optimizing
232+ - ** Real-world scenarios** - Tests diverse URL patterns (ASCII, IDN, IPv6, percent-encoded, etc.)
233+ - ** Actionable metrics** - Reports average µs/URL and throughput (URLs/second)
234+ - ** Optional** - Not required for normal development (disabled by default)
235+
236+ ### Building Benchmarks
237+
238+ ``` bash
239+ cmake \
240+ -B _build \
241+ -G " Ninja" \
242+ -Dskyr_BUILD_BENCHMARKS=ON \
243+ .
244+ cmake --build _build --target url_parsing_bench
245+ ```
246+
247+ ### Running Benchmarks
248+
249+ ``` bash
250+ # Default: 10,000 iterations × 34 URLs = 340,000 parses
251+ ./_build/benchmark/url_parsing_bench
252+
253+ # Custom iteration count (100,000 iterations)
254+ ./_build/benchmark/url_parsing_bench 100000
255+
256+ # Quick test (1,000 iterations)
257+ ./_build/benchmark/url_parsing_bench 1000
258+ ```
259+
260+ ### Example Output
261+
262+ ```
263+ =================================================
264+ URL Parsing Benchmark Results
265+ =================================================
266+
267+ Configuration:
268+ Test URLs: 34 unique patterns
269+ Iterations: 10000
270+ Total URLs: 340000
271+
272+ Results:
273+ Total time: 820 ms
274+ Successful: 330000 (97.1%)
275+ Failed: 10000 (2.9%)
276+
277+ Performance:
278+ Average: 2.412 µs/URL
279+ Throughput: 414634 URLs/second
280+
281+ =================================================
282+ ```
283+
284+ ### Interpreting Results
285+
286+ ** Good performance (on modern hardware):**
287+ - Average: < 5 µs/URL
288+ - Throughput: > 200,000 URLs/second
289+
290+ ** Investigate if:**
291+ - Average: > 10 µs/URL
292+ - Throughput: < 100,000 URLs/second
293+
294+ ### Profiling
295+
296+ To find actual performance bottlenecks, use profiling tools:
297+
298+ ** macOS (Instruments):**
299+ ``` bash
300+ cmake -B _build -G Ninja -Dskyr_BUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
301+ cmake --build _build --target url_parsing_bench
302+ instruments -t " Time Profiler" -D /tmp/url_bench.trace ./_build/benchmark/url_parsing_bench 50000
303+ open /tmp/url_bench.trace
304+ ```
305+
306+ ** Linux (perf):**
307+ ``` bash
308+ cmake -B _build -G Ninja -Dskyr_BUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
309+ cmake --build _build --target url_parsing_bench
310+ perf record -g ./_build/benchmark/url_parsing_bench 50000
311+ perf report
312+ ```
313+
314+ ** All platforms (Valgrind):**
315+ ``` bash
316+ valgrind --tool=callgrind ./_build/benchmark/url_parsing_bench 1000
317+ qcachegrind callgrind.out # or kcachegrind on Linux
318+ ```
319+
320+ ### Test Coverage
321+
322+ The benchmark tests 34 diverse URL patterns:
323+ - Simple ASCII URLs (http, https, ftp)
324+ - URLs with query parameters and fragments
325+ - URLs with authentication (user: pass @host)
326+ - URLs with non-default ports
327+ - Internationalized domain names (IDN): ` http://example.إختبار/ ` , ` https://münchen.de/ `
328+ - Unicode in paths: ` http://example.com/π ` , ` https://example.org/文档/ `
329+ - Percent-encoded URLs: ` http://example.com/path%20with%20spaces `
330+ - Complex real-world URLs (Google search, GitHub, Wikipedia)
331+ - IPv4 addresses: ` http://192.168.1.1/ ` , ` https://127.0.0.1:8443/ `
332+ - IPv6 addresses: ` http://[::1]/ ` , ` https://[2001:db8::1]/ `
333+ - Edge cases: file://, data:, mailto:
334+
335+ ### Performance Expectations
336+
337+ ** Typical results on modern hardware (Apple M1/M2, Intel i7+, AMD Ryzen):**
338+ - Average: 2-4 µs/URL
339+ - Throughput: 250,000 - 500,000 URLs/second
340+
341+ ** Why this is fast enough:**
342+ - Most applications parse URLs once per request
343+ - A typical HTTP request takes 10-100ms
344+ - URL parsing is < 0.01% of total request time
345+ - Bottleneck is almost never URL parsing
346+
347+ ### Before Adding Dependencies
348+
349+ Before adding external libraries like simdutf for "faster UTF conversion":
350+
351+ 1 . ** Profile first** - Use profiling tools to find real bottlenecks
352+ 2 . ** Measure UTF time** - Is UTF conversion > 10% of runtime?
353+ 3 . ** Consider trade-offs** - Zero dependencies vs marginal speedup
354+
355+ The benchmark helps answer: "Is optimization worth the complexity?"
356+
224357## Code Structure
225358
226359** Directory Layout** :
0 commit comments