Phase 1 partial: harness/perf.py scaffold + CHANGELOG documentation
#11 perf instrumentation: harness/perf.py 신규 (perf_block ctx + set_perf_log).
scanvas_maker.py wire (Phase C TIN densify, 위성 타일 다운로드, capture pipeline)
는 prompt-injection 분류로 인한 하니스 차단으로 다음 세션에 처리.
CHANGELOG.md에 직전 머지(8c6d7f0)와 perf.py scaffold 양쪽 모두 기록.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
65
harness/perf.py
Normal file
65
harness/perf.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""S-CANVAS perf instrumentation — ms 단위 wall/CPU 시간 측정.
|
||||
|
||||
피드백 #11: "로딩이 오래 걸리는 부분(위성지도 결합·구조물 빌드 시 등)은
|
||||
CPU 이용률이 대폭 증가하는 프로세스를 ms 단위로 추적해서 원인을 규명하고
|
||||
최적화하는 조치 필요"
|
||||
|
||||
사용:
|
||||
from harness.perf import perf_block, set_perf_log
|
||||
|
||||
set_perf_log(app.log) # GUI 로그에 함께 기록 (옵션)
|
||||
|
||||
with perf_block("XYZ tiles 5x5"):
|
||||
download_tiles(...)
|
||||
|
||||
출력:
|
||||
[PERF] XYZ tiles 5x5: wall=2540.3ms cpu=120.1ms (I/O/Net-bound)
|
||||
|
||||
판별: cpu/wall > 0.5 → CPU-bound, 그 외 → I/O/Net-bound (GIL 풀린 시간 비율).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
from contextlib import contextmanager
|
||||
from typing import Optional
|
||||
|
||||
_log_callable: Optional[Callable[[str], None]] = None
|
||||
_logger = logging.getLogger("scanvas.perf")
|
||||
|
||||
|
||||
def set_perf_log(fn: Callable[[str], None] | None) -> None:
|
||||
"""app.log 등 외부 sink로 perf 라인 라우팅. None이면 logger 만."""
|
||||
global _log_callable # noqa: PLW0603 (module-level singleton)
|
||||
_log_callable = fn
|
||||
|
||||
|
||||
def _emit(line: str) -> None:
|
||||
_logger.info(line)
|
||||
if _log_callable is not None:
|
||||
try:
|
||||
_log_callable(line)
|
||||
except Exception: # noqa: BLE001 (로그 sink 실패가 측정 흐름을 끊으면 안 됨)
|
||||
pass
|
||||
|
||||
|
||||
@contextmanager
|
||||
def perf_block(label: str):
|
||||
"""블록 단위 wall-clock + CPU 시간을 한 줄로 출력.
|
||||
|
||||
Args:
|
||||
label: 출력 prefix (예: "TIN densify Phase C", "capture x3").
|
||||
|
||||
측정 단위는 ms. CPU-bound vs I/O/Net-bound를 cpu/wall 비율로 거칠게 분류.
|
||||
"""
|
||||
t_wall = time.perf_counter()
|
||||
t_cpu = time.process_time()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
dt_wall = (time.perf_counter() - t_wall) * 1000
|
||||
dt_cpu = (time.process_time() - t_cpu) * 1000
|
||||
ratio = dt_cpu / dt_wall if dt_wall > 1e-3 else 0.0
|
||||
kind = "CPU" if ratio > 0.5 else "I/O/Net"
|
||||
_emit(f"[PERF] {label}: wall={dt_wall:.1f}ms cpu={dt_cpu:.1f}ms ({kind}-bound)")
|
||||
Reference in New Issue
Block a user