pydantic model generator for atproto lexicons
1#!/usr/bin/env -S uv run python
2"""benchmark pmgfal on real lexicons."""
3
4import subprocess
5import tempfile
6import time
7from pathlib import Path
8
9
10def bench_atproto():
11 """benchmark against full atproto lexicons."""
12 with tempfile.TemporaryDirectory() as tmp:
13 # clone atproto
14 print("cloning atproto lexicons...")
15 subprocess.run(
16 [
17 "git",
18 "clone",
19 "--depth=1",
20 "https://github.com/bluesky-social/atproto.git",
21 tmp,
22 ],
23 capture_output=True,
24 check=True,
25 )
26
27 lexicon_dir = Path(tmp) / "lexicons"
28 output_dir = Path(tmp) / "output"
29 json_files = list(lexicon_dir.rglob("*.json"))
30
31 print(f"found {len(json_files)} lexicon files")
32
33 # benchmark generation (cold)
34 start = time.perf_counter()
35 subprocess.run(
36 [
37 "uv",
38 "run",
39 "pmgfal",
40 str(lexicon_dir),
41 "-o",
42 str(output_dir),
43 "--no-cache",
44 ],
45 check=True,
46 )
47 cold_time = time.perf_counter() - start
48
49 # count output
50 models_file = output_dir / "models.py"
51 lines = len(models_file.read_text().splitlines()) if models_file.exists() else 0
52
53 # benchmark cache hit
54 start = time.perf_counter()
55 subprocess.run(
56 ["uv", "run", "pmgfal", str(lexicon_dir), "-o", str(output_dir)],
57 check=True,
58 )
59 cache_time = time.perf_counter() - start
60
61 print("\nresults:")
62 print(f" lexicons: {len(json_files)}")
63 print(f" output: {lines} lines")
64 print(f" cold generation: {cold_time:.3f}s")
65 print(f" cache hit: {cache_time:.3f}s")
66
67
68if __name__ == "__main__":
69 bench_atproto()