Phase 1 (#11): wire perf_block into scanvas_maker.py at 4 hotspots
- import + 폴백 (line ~58): from harness.perf import perf_block, set_perf_log
ImportError 시 contextlib.contextmanager 노옵으로 안전 폴백.
- SCanvasApp.__init__ (line ~613): set_perf_log(self.log) — GUI 패널에 perf 라인 표시.
- TIN densify Phase C (line ~4430): with perf_block("TIN densify Phase C (10m→1m)").
- 위성 타일 다운로드 (line ~5384): with perf_block("위성 타일 다운로드+병합").
- 제어맵 캡처 x3 + composite (line ~5864): with perf_block("control map capture x3 + composite").
검증: py_compile + AST parse OK. 글로벌 ruff 미설치라 ruff Green 검증은 다음
세션 (uv pip install -e ".[dev]" 후).
CHANGELOG.md에 wire 내역 + 측정 출력 예시 추가.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
23
CHANGELOG.md
23
CHANGELOG.md
@@ -10,6 +10,29 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-05-08 (후속 — wire)
|
||||||
|
|
||||||
|
### [feat] `scanvas_maker.py`에 `perf_block` wire 완료 (#11)
|
||||||
|
|
||||||
|
- **수정 파일**: `scanvas_maker.py` (5곳).
|
||||||
|
- **목적**: harness/perf.py scaffold가 즉시 동작하도록 핫스팟에 `with perf_block(...)` 래핑.
|
||||||
|
- **변경 위치**:
|
||||||
|
1. **import 블록 (~line 58)**: `from harness.perf import perf_block, set_perf_log` + ImportError 시 `@contextlib.contextmanager` 노옵 폴백.
|
||||||
|
2. **`SCanvasApp.__init__` (~line 613)**: `set_perf_log(self.log)` 등록 — perf 측정 라인이 GUI 텍스트박스에도 표시됨.
|
||||||
|
3. **TIN densify Phase C (line ~4430)**: `with perf_block("TIN densify Phase C (10m→1m)")` 로 10단계 점진 격자 루프 감쌈.
|
||||||
|
4. **위성 타일 다운로드 (line ~5384)**: `with perf_block("위성 타일 다운로드+병합")` 로 `_download_xyz_tiles()` 감쌈 — 사용자 피드백 #11이 명시한 "위성지도 결합" 핫스팟.
|
||||||
|
5. **제어맵 캡처 파이프라인 (line ~5864)**: `with perf_block("control map capture x3 + composite")` 로 textured + depth + lineart 3-stage 캡처 + composite 감쌈 (PERFORMANCE_BASELINE.md H12).
|
||||||
|
- **출력 예 (실제 측정 시)**:
|
||||||
|
```
|
||||||
|
[PERF] 위성 타일 다운로드+병합: wall=12340.5ms cpu=860.3ms (I/O/Net-bound)
|
||||||
|
[PERF] TIN densify Phase C (10m→1m): wall=2150.7ms cpu=2080.4ms (CPU-bound)
|
||||||
|
[PERF] control map capture x3 + composite: wall=4520.1ms cpu=3760.8ms (CPU-bound)
|
||||||
|
```
|
||||||
|
- **검증**: `python -m py_compile scanvas_maker.py harness/perf.py` 통과. AST parse OK. ruff는 글로벌 미설치 환경이라 다음 세션 uv install 후 검증 (`uv pip install -e ".[dev]"; ruff check`).
|
||||||
|
- **다음**: 핫스팟 H1·H7·H9·H12·H13·H18 등 추가 측정 위치 확장은 본 라운드 미적용. 사용자 실제 도면으로 한 번 측정 후 PERFORMANCE_BASELINE.md 의 "측정 후 비교 표" 채울 때 결정.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-05-08
|
## 2026-05-08
|
||||||
|
|
||||||
### [merge] Gitea s-canvas 원격(raw upload, 184185c)과 로컬 lint+Phase 0 history 통합
|
### [merge] Gitea s-canvas 원격(raw upload, 184185c)과 로컬 lint+Phase 0 history 통합
|
||||||
|
|||||||
@@ -55,6 +55,16 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
HARNESS_AVAILABLE = False
|
HARNESS_AVAILABLE = False
|
||||||
|
|
||||||
|
# Perf instrumentation (#11) — ms 단위 wall/CPU 측정. import 실패 시 no-op 폴백.
|
||||||
|
try:
|
||||||
|
from harness.perf import perf_block, set_perf_log
|
||||||
|
except ImportError:
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def perf_block(label): # type: ignore[no-redef]
|
||||||
|
yield
|
||||||
|
def set_perf_log(fn): # type: ignore[no-redef]
|
||||||
|
pass
|
||||||
|
|
||||||
# 구조물 상세도면 치수 파서
|
# 구조물 상세도면 치수 파서
|
||||||
try:
|
try:
|
||||||
from detail_parser import DetailParser, dimensions_to_structure_params
|
from detail_parser import DetailParser, dimensions_to_structure_params
|
||||||
@@ -610,6 +620,10 @@ class SCanvasApp(ctk.CTk):
|
|||||||
|
|
||||||
self.log("S-CANVAS Generative Design Engine 구동 완료.")
|
self.log("S-CANVAS Generative Design Engine 구동 완료.")
|
||||||
|
|
||||||
|
# Perf 측정 라인을 GUI 로그에도 함께 표시 (#11). harness/perf.py 폴백 import 시
|
||||||
|
# set_perf_log는 no-op이라 실패해도 안전.
|
||||||
|
set_perf_log(self.log)
|
||||||
|
|
||||||
def create_sidebar_button(self, text, command, row, **kwargs):
|
def create_sidebar_button(self, text, command, row, **kwargs):
|
||||||
btn = ctk.CTkButton(
|
btn = ctk.CTkButton(
|
||||||
self.sidebar_frame, text=text, command=command, height=34, **kwargs)
|
self.sidebar_frame, text=text, command=command, height=34, **kwargs)
|
||||||
@@ -4427,6 +4441,7 @@ class SCanvasApp(ctk.CTk):
|
|||||||
from matplotlib.path import Path as _MplPath
|
from matplotlib.path import Path as _MplPath
|
||||||
total_phase_c = 0
|
total_phase_c = 0
|
||||||
steps_log = []
|
steps_log = []
|
||||||
|
with perf_block("TIN densify Phase C (10m→1m)"):
|
||||||
for _step in (10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0):
|
for _step in (10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0):
|
||||||
try:
|
try:
|
||||||
hull_c = _ConvexHull(pts[:, :2])
|
hull_c = _ConvexHull(pts[:, :2])
|
||||||
@@ -5380,6 +5395,7 @@ class SCanvasApp(ctk.CTk):
|
|||||||
if not vk:
|
if not vk:
|
||||||
raise ValueError("Vworld 타일 사용 시 API Key가 필요합니다. 사이드바에 입력해주세요.")
|
raise ValueError("Vworld 타일 사용 시 API Key가 필요합니다. 사이드바에 입력해주세요.")
|
||||||
tile_url_template = tile_url_template.replace("{vworld_key}", vk)
|
tile_url_template = tile_url_template.replace("{vworld_key}", vk)
|
||||||
|
with perf_block("위성 타일 다운로드+병합"):
|
||||||
satellite_img = self._download_xyz_tiles(tile_url_template, min_lat, min_lon, max_lat, max_lon)
|
satellite_img = self._download_xyz_tiles(tile_url_template, min_lat, min_lon, max_lat, max_lon)
|
||||||
|
|
||||||
img_path = "satellite_temp.png"
|
img_path = "satellite_temp.png"
|
||||||
@@ -5861,6 +5877,7 @@ class SCanvasApp(ctk.CTk):
|
|||||||
ar_label = f"비율 {ar[0]}:{ar[1]}" if ar else f"뷰어 창 {self._saved_window_size or '미저장'}"
|
ar_label = f"비율 {ar[0]}:{ar[1]}" if ar else f"뷰어 창 {self._saved_window_size or '미저장'}"
|
||||||
self.log(f" 캡처 해상도: {out_w}x{out_h} ({ar_label} 기반)")
|
self.log(f" 캡처 해상도: {out_w}x{out_h} ({ar_label} 기반)")
|
||||||
|
|
||||||
|
with perf_block("control map capture x3 + composite"):
|
||||||
# 1. 위성 텍스처 3D 캡처
|
# 1. 위성 텍스처 3D 캡처
|
||||||
self.capture_image = self._capture_from_camera(out_w, out_h, textured=True)
|
self.capture_image = self._capture_from_camera(out_w, out_h, textured=True)
|
||||||
self.capture_image.save("capture_textured.png")
|
self.capture_image.save("capture_textured.png")
|
||||||
|
|||||||
Reference in New Issue
Block a user