diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/design/027-computation-core.md | 10 | ||||
| -rw-r--r-- | docs/research/140-spec-suite.md | 46 |
2 files changed, 55 insertions, 1 deletions
diff --git a/docs/design/027-computation-core.md b/docs/design/027-computation-core.md index cd8dd44..7b851f6 100644 --- a/docs/design/027-computation-core.md +++ b/docs/design/027-computation-core.md @@ -137,7 +137,15 @@ - 시간은 C의 116배, 파이썬의 1.2배다. - 쓰다가 드러난 뜻의 틈 하나를 메웠다. `&&`가 양쪽을 다 계산해서 `i < n && d[i]`가 실패했다. 이제 단락 평가이고, 오른쪽이 실패할 수 없을 때는 지금처럼 AND 하나를 낸다. 그래서 TPC-C를 포함한 기존 모듈 35개가 바이트까지 같다. -- **2b:** 중첩(레코드 안의 레코드와 리스트), 갈래와 `match`, 값으로서의 리스트, 메시지 필드의 아무 값. JSON을 트리로 읽고 묻는다. +- **2b(만듦):** 레코드 안의 레코드와 리스트, 갈래와 `match`, 값으로서의 리스트, 수 읽기. 결과는 140의 2b절이다. + - **꼴.** 레코드와 갈래는 aup가 경로 이름의 열로 펼쳐, 런타임에는 레코드 값이 없다. 리스트만 런타임의 묶음 값이다. + - **칸.** 칸에는 이벤트가 만든 리스트의 번호(i64)를 담는다. 리스트의 내부, 묶음 실행기, JIT는 그대로다. JIT의 덧붙이기 빠른 길만 + 리스트 필드를 비킨다. + - **값의 뜻.** 나눠 가진 리스트는 바뀌기 전에 복사되므로 값의 뜻이 지켜진다. 읽기는 레지스터에 묶어 기존의 걷기, 접기, 자리 + 읽기를 그대로 쓴다. + - **JSON 트리.** JSONTestSuite에서 틀린 것이 없고, 무작위 문서 300개의 다이제스트가 파이썬과 같다. + - **막대.** 줄 수는 못 미쳤다(167 대 133: 타입 선언). 시간은 C(cJSON)의 40배이고, 순수 파이썬보다도 1.3배 느리다. + - **남은 것.** 메시지 필드의 아무 값(JSON 경계에서 바로 트리로)과 저장되는 리스트의 리스트는 3·4단계로 남긴다. - **2c:** 재귀(부르기와 돌아가기, 함수마다의 검증), 글자로 읽기. - 레코드의 필드와 리스트의 원소가 아무 값을 가진다. diff --git a/docs/research/140-spec-suite.md b/docs/research/140-spec-suite.md index 6231c33..67d1cec 100644 --- a/docs/research/140-spec-suite.md +++ b/docs/research/140-spec-suite.md @@ -245,6 +245,52 @@ - 남은 차이는 리스트를 값으로 짓지 못해 생기는 것(메시지 스케줄의 미리 채움), 낱말 만들기, 선언이다. - 시간은 바이트당 1,437 ns(C의 159배)다. 블록당 명령이 16,476개로 줄었다. +## 027의 2b: JSON을 트리로 (2026-10-13) + +2b에서 더한 것: +- **aup.** + - 레코드 안의 레코드(경로 이름의 열로 펼침), 갈래(`variant`), `match` + - 리스트를 담은 필드(`items: list of Json`)와 그 덧붙이기(`x.items.append`) + - 키 없는 리스트의 `xs[i]` 항목, `number(t)` +- **Pure.** + - 레코드 필드의 타입 LIST: 칸에는 이벤트가 만든 리스트의 번호를 담는다. + - 명령 넷(LIST_VALUE, LIST_BIND, APPEND_IN, NUM_PARSE)과 레지스터 플래그, 경로 이름의 레코드 필드 +- 나눠 가진 리스트는 바뀌기 전에 복사된다. 그래서 다른 값은 바뀌지 않는다(단위 시험이 복사, 나눔 뒤의 덧붙이기, 묶인 레지스터를 + 본다). ASan·UBSan 빌드의 단위 시험도 지났다. UBSan이 레코드 종류 표의 빈자리를 잡아 고쳤다. + +**JSON 트리.** aup의 `examples/json_tree.aup`는 JSON 텍스트를 `Json` 갈래의 트리로 읽는다. +- 열린 배열과 객체는 스택(`list of Open`)에 두고, 값은 그 맨 위 항목의 리스트 필드에 덧붙인다. 닫을 때는 그 리스트를 값으로 + 부모에게 넘긴다(나눠 가짐, 복사 없음). 문자열의 이스케이프(서로게이트 쌍 포함)를 풀고, 수는 `number(t)`로 읽는다. +- 그다음 트리를 너비 우선으로 돌아 다이제스트를 낸다: 종류별 수, 수의 합, 문자열과 키의 바이트. + +**맞음.** 파이썬의 `json.loads`(같은 키가 둘인 객체를 지키려고 쌍 목록으로)를 같은 순서로 돈 다이제스트와 견준다. +- JSONTestSuite에서 틀린 것이 없다. `y_` 95개를 모두 받아 다이제스트가 같고(수의 합은 비트까지), `n_`은 하나도 받지 않는다. +- `i_`는 6개를 받는다: 아주 큰 정수, 언더플로, 500겹. 범위를 넘는 지수(유한하지 않은 수)와 짝 없는 서로게이트(UTF-8이 아닌 text)는 + 실패로 거절한다. +- 무작위 중첩 문서 300개(10만 바이트: 이스케이프, 이모지, 제어 문자, 깊이 5)가 모두 같다. +- 세 실행 길이 같다. Pure의 `make check`(`module_specs`)에 JSONTestSuite와 무작위 문서 100개로 들어갔다. + +**막대.** + +| 막대 | 잰 것 | | +|---|---|---| +| 공식 케이스 | `y_` 모두 받음, `n_` 모두 거절 | 지남 | +| 줄 수 ≤ 파이썬 참조 | aup 167줄(닫는 괄호만인 줄 20) 대 같은 설계의 파이썬 133줄 | **못 미침** | +| 시간 | 바이트당 556 ns. C(cJSON, 같은 다이제스트) 14 ns(40배), 같은 설계의 순수 파이썬 428 ns(Pure가 1.3배 느림), 파이썬의 C `json` 모듈 61 ns | 기록 | + +**줄을 길게 한 것.** +- 타입 선언이다: `Json` 갈래 8줄, `Member`와 `Open` 10줄, 다이제스트의 상태 11줄. 파이썬은 동적 타입이라 쓰지 않는다. +- `match`의 갈래 블록 괄호도 있다. +- 리스트를 다루는 줄 자체는 짧아졌다(닫을 때 한 줄, 덧붙이기 한 줄). + +**시간이 가는 곳.** +- 바이트당 Pure 명령이 525개다. 바이트를 하나 읽을 때마다 지역 칸 읽기, 자리 읽기, fn의 인자 꺼내기, 비교가 이어진다. +- 검사기(339개)보다 많은 것은 문자열을 바이트로 모으고 값을 리스트에 놓는 일이다. +- 바이트와 텍스트의 일이 실행기에서 파이썬보다 느리다는 것이 2a(1.2배)에 이어 다시 드러났다. 핵이 선 뒤 빠르게 할 과녁의 첫째다. + +원본: `research/experiments/044-specs/json_tree.py`(파이썬 참조), `json_tree_time.c`(cJSON과 견줌, 다이제스트가 같아야 잰다), +`2026-10-13-stage2b.jsonl`. + ## 착수 기준 (다음 일) - **바꿀 결정.** 계산의 핵을 설계한다(027). 위 표의 여덟 후보 가운데 무엇을 어떤 모양으로 받을지 정한다. |
