107 lines
4.1 KiB
Python
107 lines
4.1 KiB
Python
"""ASV benchmarks for scale fixture processing.
|
|
|
|
Measures the performance of:
|
|
- Fixture metadata loading and parsing
|
|
- Threshold matrix validation
|
|
- File distribution generation from scale profiles
|
|
- Language mix validation
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import math
|
|
from pathlib import Path
|
|
|
|
_FIXTURES_DIR = Path(__file__).resolve().parents[1] / "features" / "fixtures" / "scale"
|
|
|
|
|
|
def _load_fixture(filename: str) -> dict:
|
|
"""Load a JSON fixture file from the scale fixtures directory."""
|
|
path = _FIXTURES_DIR / filename
|
|
with open(path) as fh:
|
|
return json.load(fh)
|
|
|
|
|
|
class ScaleFixtureSuite:
|
|
"""Benchmarks for scale fixture processing."""
|
|
|
|
timeout = 120
|
|
|
|
def setup(self) -> None:
|
|
"""Load scale fixtures for benchmark use."""
|
|
self.metadata_path = _FIXTURES_DIR / "scale_metadata.json"
|
|
self.thresholds_path = _FIXTURES_DIR / "baseline_thresholds.json"
|
|
self.metadata = _load_fixture("scale_metadata.json")
|
|
self.thresholds = _load_fixture("baseline_thresholds.json")
|
|
|
|
def time_metadata_loading(self) -> None:
|
|
"""Benchmark fixture metadata loading from disk."""
|
|
_load_fixture("scale_metadata.json")
|
|
|
|
def time_threshold_loading(self) -> None:
|
|
"""Benchmark threshold fixture loading from disk."""
|
|
_load_fixture("baseline_thresholds.json")
|
|
|
|
def time_threshold_validation(self) -> None:
|
|
"""Benchmark threshold matrix validation logic."""
|
|
data = self.thresholds
|
|
for section in ("indexing", "decomposition"):
|
|
for _file_count, thresholds in data[section].items():
|
|
p50 = thresholds["p50_ms"]
|
|
p95 = thresholds["p95_ms"]
|
|
p99 = thresholds["p99_ms"]
|
|
assert p50 < p95 < p99
|
|
|
|
def time_language_mix_validation(self) -> None:
|
|
"""Benchmark language mix sum validation across all profiles."""
|
|
for profile in self.metadata["scale_profiles"]:
|
|
total = sum(profile["language_mix"].values())
|
|
assert math.isclose(total, 1.0, rel_tol=1e-6)
|
|
|
|
def time_file_distribution_generation(self) -> None:
|
|
"""Benchmark file distribution generation for all profiles."""
|
|
for profile in self.metadata["scale_profiles"]:
|
|
total = profile["file_count"]
|
|
mix = profile["language_mix"]
|
|
distribution: dict[str, int] = {}
|
|
allocated = 0
|
|
items = sorted(mix.items(), key=lambda x: x[1], reverse=True)
|
|
for i, (lang, ratio) in enumerate(items):
|
|
if i == len(items) - 1:
|
|
distribution[lang] = total - allocated
|
|
else:
|
|
count = round(total * ratio)
|
|
distribution[lang] = count
|
|
allocated += count
|
|
assert sum(distribution.values()) == total
|
|
|
|
def time_full_fixture_roundtrip(self) -> None:
|
|
"""Benchmark complete fixture load + validate + distribute cycle."""
|
|
metadata = _load_fixture("scale_metadata.json")
|
|
thresholds = _load_fixture("baseline_thresholds.json")
|
|
|
|
# Validate thresholds
|
|
for section in ("indexing", "decomposition"):
|
|
for _file_count, thresh in thresholds[section].items():
|
|
assert thresh["p50_ms"] < thresh["p95_ms"] < thresh["p99_ms"]
|
|
|
|
# Validate and generate distributions
|
|
for profile in metadata["scale_profiles"]:
|
|
total_mix = sum(profile["language_mix"].values())
|
|
assert math.isclose(total_mix, 1.0, rel_tol=1e-6)
|
|
|
|
total = profile["file_count"]
|
|
mix = profile["language_mix"]
|
|
distribution: dict[str, int] = {}
|
|
allocated = 0
|
|
items = sorted(mix.items(), key=lambda x: x[1], reverse=True)
|
|
for i, (lang, ratio) in enumerate(items):
|
|
if i == len(items) - 1:
|
|
distribution[lang] = total - allocated
|
|
else:
|
|
count = round(total * ratio)
|
|
distribution[lang] = count
|
|
allocated += count
|
|
assert sum(distribution.values()) == total
|