perf(531-6): D03 [분석] 속도 — 연도 구간 나란히 프로세스 · 계류 거르기 · 결과 차 0
- 연도 구간을 프로세스 min(연도 수, PLAN_ANALYZE_WORKERS 기본 3)로 나란히 · 끝난 구간은 B 기억 비움 - 저장본이 있는 구간만 이 프로세스에서 지문 확인(다시 [분석] 빠른 길 그대로) - 계류 거르기: 지형 상자 칸마다 닿는 거리 안의 선만 엔진에 줌 — 계류 거리 · 건너기 · 격자 거리 같음 - 실측(3연도 6.5 km 찬 상태): 797.5 s · 1264 MB → 287.7 s · 합 1942 MB · 갈래 넷 좌표 · 잰 값 차 0 - 시험: 나란히 = 차례 결과 같음 · 계류 거르기 거리 · 교차 같음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,7 @@ SEGMENTS = [
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def hill() -> Terrain:
|
||||
def _hill() -> Terrain:
|
||||
x = np.arange(0.0, 1102.0, 2.0)
|
||||
y = np.arange(0.0, 402.0, 2.0)
|
||||
xx, yy = np.meshgrid(x, y)
|
||||
@@ -26,6 +25,16 @@ def hill() -> Terrain:
|
||||
return Terrain(x, y, z, np.ones(xx.shape, dtype=bool))
|
||||
|
||||
|
||||
def hill_loader(root, selection, models_dir, cache_dir):
|
||||
"""나란히 셈 프로세스가 이름으로 부르는 지형(모듈 맨 위 함수)."""
|
||||
return _hill(), []
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def hill() -> Terrain:
|
||||
return _hill()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def run(tmp_path, hill):
|
||||
_POOLS.clear()
|
||||
@@ -37,7 +46,7 @@ def run(tmp_path, hill):
|
||||
|
||||
def go(criteria=CRITERIA, corridor_m=150.0):
|
||||
return analyze.analyze_plan(
|
||||
tmp_path, SEGMENTS, criteria, loader=loader, corridor_m=corridor_m
|
||||
tmp_path, SEGMENTS, criteria, loader=loader, corridor_m=corridor_m, workers=1
|
||||
)
|
||||
|
||||
go.calls = calls
|
||||
@@ -91,6 +100,54 @@ def test_same_input_reads_store(run, monkeypatch) -> None:
|
||||
run(criteria={**CRITERIA, "max_grade": 0.12})
|
||||
|
||||
|
||||
def test_parallel_years_match_sequential(tmp_path) -> None:
|
||||
"""연도 구간 나란히(프로세스 둘) = 차례로 — 갈래 넷 노선 좌표 · 잰 값 차 0(531-6)."""
|
||||
_POOLS.clear()
|
||||
seq = analyze.analyze_plan(
|
||||
tmp_path / "a", SEGMENTS, CRITERIA, loader=hill_loader, corridor_m=150.0, workers=1
|
||||
)
|
||||
_POOLS.clear()
|
||||
steps = []
|
||||
par = analyze.analyze_plan(
|
||||
tmp_path / "b",
|
||||
SEGMENTS,
|
||||
CRITERIA,
|
||||
loader=hill_loader,
|
||||
corridor_m=150.0,
|
||||
workers=2,
|
||||
on_progress=lambda p, m: steps.append(m),
|
||||
)
|
||||
assert [r["routes"] for r in par] == [r["routes"] for r in seq]
|
||||
assert [r["fingerprint"] for r in par] == [r["fingerprint"] for r in seq]
|
||||
assert "나란히 2" in steps[0] and steps[-1] == "분석 끝"
|
||||
# 저장본은 제 프로세스에서 지문만 보고 그대로
|
||||
again = analyze.analyze_plan(
|
||||
tmp_path / "b", SEGMENTS, CRITERIA, loader=hill_loader, corridor_m=150.0, workers=2
|
||||
)
|
||||
assert [r["stored"] for r in again] == [True, True]
|
||||
_POOLS.clear()
|
||||
|
||||
|
||||
def test_near_streams_keeps_every_nearest_line(hill) -> None:
|
||||
"""계류 거르기 — 지형 상자 안 점의 계류 거리 · 건너기가 통째와 같고 먼 선은 빠짐(531-6)."""
|
||||
import shapely
|
||||
from shapely.geometry import LineString, MultiLineString
|
||||
|
||||
rng = np.random.default_rng(7)
|
||||
streams = []
|
||||
for _ in range(80): # 지형(1.1 × 0.4 km) 둘레 5 km 에 흩은 계류
|
||||
start = rng.uniform(-2000.0, 3000.0, 2)
|
||||
streams.append([tuple(start + step) for step in np.cumsum(rng.normal(0, 60, (6, 2)), 0)])
|
||||
kept = analyze.near_streams(hill, streams)
|
||||
assert 0 < len(kept) < len(streams)
|
||||
points = shapely.points(rng.uniform((0.0, 0.0), (1100.0, 400.0), (4000, 2)))
|
||||
whole, part = MultiLineString(streams), MultiLineString(kept)
|
||||
assert np.array_equal(shapely.distance(points, whole), shapely.distance(points, part))
|
||||
route = LineString([(0.0, 0.0), (1100.0, 400.0)])
|
||||
assert route.intersection(whole).equals(route.intersection(part))
|
||||
assert analyze.near_streams(hill, []) == []
|
||||
|
||||
|
||||
def test_corridor_argument_keeps_b_default(hill) -> None:
|
||||
line = [SEGMENTS[0]["start"], SEGMENTS[0]["end"]]
|
||||
base = SearchGrid(line, hill, [], stream_offset_m=10.0)
|
||||
|
||||
Reference in New Issue
Block a user