Files
Aislo/resources/tester/run_511_b5_route_save_timing.py
T

115 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
"""511-B B-5 노선 저장 체인 시간 · 값 — 검증 프로젝트의 지금 노드 · 편집표 그대로 저장(수동 실행).
같은 노선이라 값은 그대로(새 노선 행 번호만 바뀜) · 초기값 안 건드림(`as_initial` 끔).
갈래 = 파이썬 짝(Node 폴리라인 · 좌표 맞춤 끔) / Node 를 번갈아 N 번 · 저장 뒤 정본 파일 해시
(노선 csv · 노드 · 곡선표 · 구조물 · 관 · 추가 측점 · 종단 · 횡단)가 처음과 같은지.
쓰는 법: `./venv/Scripts/python.exe resources/tester/run_511_b5_route_save_timing.py <id> [N]`
"""
import asyncio
import hashlib
import json
import logging
import statistics
import sys
import time
from pathlib import Path
from uuid import UUID
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from config.config_db import close_db_pool, init_db_pool # noqa: E402
CANON = (
"B05_Profile/route/planned_route.csv",
"B05_Profile/route/planned_route_nodes.csv",
"B05_Profile/route/planned_route_curves.json",
"B05_Profile/route/route_main.geojson",
"B05_Profile/route/structures.json",
"B05_Profile/route/plus_stations.json",
"B04_PreProcess/drainage/edits/pipe_points.json",
)
def _hashes(root: Path) -> dict[str, str]:
files = [root / name for name in CANON]
files += sorted((root / "B06_Section").rglob("*.json"))
return {
str(path.relative_to(root)): hashlib.sha256(path.read_bytes()).hexdigest()[:16]
for path in files
if path.is_file()
}
async def _save(project_id: UUID, python: bool) -> float:
from B05_Profile import B05_Profile_Route_Polyline_Write as writer
from B05_Profile import B05_Profile_Router_Replan as replan
from B05_Profile.B05_Profile_Route_Save import RouteSaveRequest
from common_util import common_util_route_follow as follow
plan = await replan.read_route_plan(project_id)
edits = plan["node_edits"]
body = RouteSaveRequest(
vertices=[
{"x": n["x"], "y": n["y"], "curve": e["curve"], "radius_m": e["radius_m"]}
for n, e in zip(plan["nodes"], edits, strict=True)
],
station_snap=bool(plan.get("station_snap")),
station_snap_step=plan.get("station_snap_step"),
)
real = (writer.node_polyline, follow.fill_structure_coordinates)
if python:
writer.node_polyline = lambda *a: None
follow.fill_structure_coordinates = follow._fill_structure_coordinates_py
try:
started = time.perf_counter()
result = await replan.replan_route(project_id, body)
seconds = time.perf_counter() - started
finally:
writer.node_polyline, follow.fill_structure_coordinates = real
status = getattr(result, "status_code", 200)
assert status == 200, getattr(result, "body", result)
return seconds
async def main(project_id: UUID, rounds: int) -> None:
from B05_Profile import B05_Profile_Router_Replan as replan
logging.basicConfig(level=logging.WARNING, format="%(message)s")
await init_db_pool()
try:
root, _ = await replan._project_paths(project_id)
first = _hashes(root)
times: dict[str, list[float]] = {"python": [], "node": []}
for _ in range(rounds):
for kind in ("python", "node"):
times[kind].append(await _save(project_id, kind == "python"))
after = _hashes(root)
changed = sorted(
k for k in first.keys() | after.keys() if first.get(k) != after.get(k)
)
print(f"{kind}: {times[kind][-1]:.2f} s · 바뀐 정본 {len(changed)} {changed[:5]}")
print(
json.dumps(
{
k: {
"median_s": round(statistics.median(v), 2),
"runs": [round(x, 2) for x in v],
}
for k, v in times.items()
},
ensure_ascii=False,
)
)
finally:
from common_util.common_util_calc_runner import _SERVED
_SERVED.stop()
await close_db_pool()
if __name__ == "__main__":
asyncio.run(main(UUID(sys.argv[1]), int(sys.argv[2]) if len(sys.argv) > 2 else 3))