aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/012-refresh-ownership.md
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-24 17:14:54 +0100
committereunhhu <[email protected]>2026-09-24 17:14:54 +0100
commitb1ce1927022d374198441afafeb27199fc8a052a (patch)
tree6021f175f4c67ed03b44240eaa2f90d846f12f6f /docs/research/012-refresh-ownership.md
parentd34f9426d5317a1948f12f229439946728bc342a (diff)
downloadpure-b1ce1927022d374198441afafeb27199fc8a052a.tar.gz
pure-b1ce1927022d374198441afafeb27199fc8a052a.zip
Establish native micro runtime checkpoint
Diffstat (limited to 'docs/research/012-refresh-ownership.md')
-rw-r--r--docs/research/012-refresh-ownership.md100
1 files changed, 100 insertions, 0 deletions
diff --git a/docs/research/012-refresh-ownership.md b/docs/research/012-refresh-ownership.md
new file mode 100644
index 0000000..d9fde5d
--- /dev/null
+++ b/docs/research/012-refresh-ownership.md
@@ -0,0 +1,100 @@
+# Pure 012: 실행 입력이 편집기를 다시 계산하던 경로 제거
+
+작성일: 2026-09-23. 실제 작성 도구 변경, 단계별 프로파일과 브라우저 비교.
+
+## 알아낸 것과 바뀐 동작
+
+011에서 DOM 재생성을 없앴지만 시간이 줄지 않았다. 다음 변경에 앞서 비용을 나눠 측정하니
+출력 계산·전달보다 **바뀌지도 않은 소스 편집기의 정보를 갱신하는 경로**가 더 컸다.
+입력 이벤트마다 `refresh()`가 줄 번호, UTF-8 바이트 수, 스크롤, 커서 위치를 갱신했다.
+입력과 코드 편집은 독립적인데 하나의 갱신 함수로 묶여 있었다.
+
+실행 갱신에서 이 경로를 제거했다. 실제 소스 변경에서만 편집기 정보를 갱신하고,
+코드 적용은 초안과 적용된 정의의 일치 상태만 갱신한다.
+화면에 이미 같은 값이 있으면 상태·진단·버튼 속성도 다시 쓰지 않는다.
+새 캐시, 구독 그래프, 이벤트 버스, VM 명령이나 런타임 계층을 추가하지 않았다.
+
+사용자는 전과 같이 코드를 작성하고, 키보드·화면 버튼·프레임으로 동작시킨다.
+실행 중에도 미적용 초안은 그대로 남고 코드 편집·적용·오류 위치 이동의 표시가 갱신된다.
+이번 결과는 **불필요한 갱신 연결을 제거한 구현 개선**이다. 새로운 계산 원리의 발견은 아니다.
+
+## 먼저 확인한 비용
+
+24개 출력, 상태 하나, 입력 하나를 작성했다. 이동 입력은 x를 0.25 늘리고 도형과 텍스트에 반영된다.
+준비 입력 20회 뒤 입력 100회(누름·해제 200사건)를 처리했다.
+기존 app 모듈의 테스트 전용 응답에 타이머를 삽입해 한 차례 프로파일했다.
+
+| 구간 | 호출 수 | 누적 시간 |
+|---|---:|---:|
+| 계산·출력 전달 `present` | 200 | 26.6 ms |
+| 비용 표시 | 200 | 56.6 ms |
+| 편집기 정보 갱신 | 200 | 259.1 ms |
+| 전체 `refresh` | 200 | 359.6 ms |
+
+전체 입력 묶음은 375.9 ms였다. 부분 구간은 refresh 안에 포함되므로 합산하지 않는다.
+CDP는 이 구간 주변에서 레이아웃 201회와 레이아웃 시간 177.7 ms를 기록했다.
+줄 번호를 쓴 뒤 스크롤 위치를 읽는 경로도 있었다. 이 관찰을 근거로 편집기 갱신 연결을
+먼저 제거했으며, 바인딩 캐시나 출력 평가 정책은 변경하지 않았다.
+
+## 변경 전후 비교
+
+직전 구현의 소스를 보존했다. before 실행에서는 app.js만 테스트 응답으로 교체한다.
+런타임·출력 어댑터·컴파일러·Wasm·작성된 소스는 양쪽이 동일하다.
+프로파일 타이머는 이 비교에 넣지 않았다. 인코딩 호출과 편집기 DOM 변경을 계측했다.
+before/after 순서를 섞어 각각 3회 실행했으며 최종 상태·출력·이벤트 수와 실제 SVG 위치가 모두 같았다.
+
+| 입력 100회당 관찰값 | 이전 | 현재 |
+|---|---:|---:|
+| 소스 UTF-8 인코딩 호출 | 400 | **0** |
+| 인코딩 결과 배열의 누적 바이트 | 410,800 B | **0 B** |
+| 편집기 정보의 DOM 변경 기록 | 800 | **0** |
+| CDP 레이아웃 횟수, 매 실행 | 201 | **1** |
+| 동기 처리 시간 중앙값 | 837.9 ms | **152.8 ms** |
+| 동기 처리 시간 범위 | 709.7–1,151.8 ms | **137.8–327.4 ms** |
+
+중앙값 기준 약 81.8% 감소다. 세 표본 모두 현재 쪽 시간이 더 짧았다.
+다만 표본 수가 작고 편차가 크며 CPU·전력·다른 프로세스를 고정하지 않았다.
+이 수치는 동일 세션의 **동기 합성 입력 dispatch부터 DOM 제출까지**다.
+실제 키 입력 도착부터 화면 표시까지의 지연이나 큰 앱의 처리량으로 일반화하지 않는다.
+계측 자체의 비용도 포함한다. CDP 카운터는 입력 묶음 전후의 브라우저 작업을 포함할 수 있다.
+이전 보고서의 별도 실행 시간과 비율을 곱하거나 서로 직접 비교하지 않는다.
+
+410,800 B는 없어진 인코딩 결과의 누적 용량이다. 피크 RAM 절감량도 전체 복사 바이트도 아니다.
+추가 런타임 버퍼는 없다. app.js의 비압축 소스는 16,014 → 16,510 B로 496 B 증가했다.
+코어·Wasm·011의 792 B 출력 버퍼와 바인딩 평가 순서는 그대로다.
+
+## 보존한 계약과 검사
+
+소스 입력, Tab 삽입, 코드 조각·파일·예제 삽입은 편집기 정보 갱신 경로를 사용한다.
+성공·실패한 코드 적용은 초안 상태를 다시 확인한다. 커서 이동·스크롤·오류 위치 이동은
+해당 표시만 갱신한다. 실행 입력·프레임·초기화는 소스 내용을 재계산하지 않는다.
+UI의 오류 문구는 완성된 문자열을 한 번에 갱신하고 기존 사건 오류·표시 오류 구분을 유지한다.
+
+브라우저 비교·편집 분리 검사 13개, 기존 작성 흐름 44개, 표시 한도·복구 12개가 통과했다.
+검사에는 Unicode 바이트 수, 줄 번호, 미적용 초안을 둔 실행·초기화, 성공/실패 적용,
+오류 위치 이동, Tab·코드 조각 삽입, 저장·복원, 키보드·포인터·모바일 동작이 포함된다.
+Zig·컴파일러·런타임은 변경하지 않았으므로 기존 52개 JS/CLI/Wasm 검사나 네이티브 검사를
+다시 실행한 것으로 세지 않는다. 이번 변경의 검증은 실제 브라우저에서 수행한다.
+
+- [변경 전 소스·해시](../../prototypes/workbench/results/2026-09-23-refresh/before/manifest.json)
+- [현재 소스·검증 기록](../../prototypes/workbench/results/2026-09-23-refresh/verification.json)
+- [원인 프로파일](../../prototypes/workbench/results/2026-09-23-refresh/profile-before.json)
+- [6회 비교와 편집 분리 검사](../../prototypes/workbench/results/2026-09-23-refresh/browser.json)
+- [작성 흐름 검사](../../prototypes/workbench/results/2026-09-23-refresh/browser-authoring.json)
+- [표시 한도·복구 검사](../../prototypes/workbench/results/2026-09-23-refresh/browser-limit.json)
+- [비교 절차](../../prototypes/workbench/qa-refresh.js), [실행 스크립트](../../prototypes/workbench/qa-refresh.py)
+
+```sh
+python3 prototypes/workbench/qa-refresh.py --cli /path/to/playwright-cli.js --session pure-path --output /tmp/pure-refresh-new.json
+```
+
+사전에 로컬 페이지를 연 Playwright CLI 0.1.21 세션이 필요하다. 결과 파일은 덮어쓰지 않는다.
+검사 종료 후 원래 모듈과 빈 작업물로 복원한다.
+
+## 결정과 남은 범위
+
+실행과 편집의 갱신 경로 분리를 채택한다. 현재 질문에 답했으므로 같은 입력의 추가 측정은 하지 않는다.
+이 결과를 ‘모든 추상화 제거가 빠르다’는 근거로 삼지 않는다. 비용이 컸던 것은 실제로 변하지 않은
+편집 자료까지 갱신하도록 연결한 경로였다. 필요한 연결과 수명은 유지한다.
+전체 표시식 평가·비용 숫자 포맷·호스트 진단 생성은 남아 있다. 자동으로 다음 미세 최적화에 들어가지 않는다.
+다음 인터페이스 확장은 사용자가 대상과 관계를 직접 조작하는 실제 요구를 기준으로 잡는다.