Skip to content

fix: 편집으로 지운 문단·그림을 레이아웃 캐시가 붙잡던 것 (포트 측정) - #57

Merged
centwon merged 1 commit into
mainfrom
perf/layout-cache-prune
Sep 28, 2026
Merged

centwon merged 1 commit into
mainfrom
perf/layout-cache-prune

Conversation

@centwon

@centwon centwon commented Sep 28, 2026

Copy link
Copy Markdown
Owner

요약

문단별 레이아웃 캐시(_layoutCache)는 10,000개를 넘을 때만 정리했고 문단을 키로 쥐어서, 편집이 문서에서 뺀 문단이 그때까지 레이아웃(~30 KB)과 함께 살아 있었다. 레이아웃의 그림 콜백(LayoutSeg.Picture)을 통해 인라인 그림의 바이트까지 남았다.

WinUI 포트가 자기 캐시를 묶은 뒤(centwon/WinUIRichEditor#59) 상류를 같은 방식으로 측정해서 찾았다.

측정 (tests/AvaloniaRichEditor.Tests.Render LayoutCacheProbe, RICHEDITOR_PERF=1, Release, 실제 Skia)

시나리오 전 후
2,000문단을 "전체 선택 + 입력" + 붙여넣기로 네 번 갈아엎음 141 → 210 → 278 → 346 MB (상한 정리 뒤 76) 80.7 MB 평평
편집으로 지운 인라인 그림 20장(40 MB), 되돌리기 제외 39.5 MB 남음 5.7 MB
지운 문단 (약한 참조) 상한 정리까지 살아 있음 정리 뒤 수거

변경

  • 내용 편집 뒤의 렌더가 마지막 편집 1초 뒤 한 번 PruneLayoutCaches를 예약한다(DispatcherTimer, 디바운스).
  • 걷기 비용: 2,000문단 ~1–2 ms, 8,000문단 ~3–5 ms — 키 입력마다는 비싸고 멈춤마다는 무시할 만하다.
  • 문서에 없는 문단의 항목만 버리므로 다시 셰이핑되는 것은 없다(테스트가 같은 TextLayout 인스턴스를 단정).

검증

  • LayoutCachePruneTests 4개 — 반증 4종(예약 안 함 / 틱이 정리 안 함 / 정리가 전부 비움 / 매 렌더 예약) 전부 빨강.
  • 전체: AvaloniaRichEditor.Tests 1,245 · Tests.Render 54 통과.
  • 측정 프로브는 RICHEDITOR_PERF=1일 때만 돈다(기존 프로브와 같은 스위치).

이번에 안 한 것

캐시가 문서 전체의 레이아웃을 쥐는 것 자체(측정·렌더·히트테스트 공유) — 문단당 20–40 KB, 모델의 6–9배, 8,000문단 ≈ 240–300 MB. 묶으려면 측정이 캐시를 쓰지 않게 해야 한다(포트는 버리는 레이아웃으로 재고 높이를 캐시한다). 별도 작업.

🤖 Generated with Claude Code

문단별 레이아웃 캐시는 10,000개를 넘을 때만 정리했고 문단을 키로 쥐어서, 편집이
문서에서 뺀 문단이 그때까지 레이아웃(~30 KB)과 함께 — 레이아웃의 그림 콜백을 통해
인라인 그림의 바이트까지 — 살아 있었다. Tests.Render LayoutCacheProbe(실제 Skia):

- 2,000문단을 "전체 선택 + 입력" + 붙여넣기로 네 번 갈아엎으면 관리 힙
  141 → 346 MB(상한 정리 뒤 76 MB). 이제 81 MB로 평평.
- 편집으로 지운 인라인 그림 40 MB 중 39.5 MB가 남았다(되돌리기 제외). 이제 5.7 MB.

편집마다 마지막 편집 1초 뒤 한 번 정리를 예약한다(DispatcherTimer). 걷기 비용은
2,000문단 ~1–2 ms, 8,000문단 ~3–5 ms — 키 입력마다는 비싸고 멈춤마다는 무시할 만하다.
문서에 없는 문단의 항목만 버리므로 다시 셰이핑되는 것은 없다.

테스트 +4(LayoutCachePruneTests), 반증 4종 전부 빨강. 1,245 + 렌더 54 통과.
캐시가 문서 전체를 쥐는 것(문단당 20–40 KB)은 그대로 — 측정 경로 분리가 필요하다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@centwon
centwon merged commit 0362021 into main Sep 28, 2026
4 checks passed
@centwon
centwon deleted the perf/layout-cache-prune branch September 28, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant