115 lines
4.2 KiB
Python
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))
|