aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-13 07:40:30 +0100
committereunhhu <[email protected]>2026-10-13 07:40:30 +0100
commit010fa06adc3b05e3e164309ee34e200f5d858fa2 (patch)
tree4fafacc583806ae1426215c14757588a444ec761 /docs/research
parent8481b12fb794690cce0d9c54032ffba3de1fe31d (diff)
downloadpure-010fa06adc3b05e3e164309ee34e200f5d858fa2.tar.gz
pure-010fa06adc3b05e3e164309ee34e200f5d858fa2.zip
Research 140, 027's stage 2b measured: JSON read into a tree (aup's examples/json_tree.aup: a variant, lists in records, match, appends into a field's list, number(t)) and walked for a digest, against Python's reading: JSONTestSuite's 95 y_ taken alike, no n_ taken, 6 i_ taken; 300 random nested documents alike; in make check (module_specs, the suite and 100 random documents, three paths); 167 lines against the same design's 133 in Python (the bar missed: the type declarations), 40 times cJSON's time and 1.3 times plain Python's (556 ns a byte, 525 instructions); json_tree.py, json_tree_time.c (cJSON linked, digests compared first)
Diffstat (limited to 'docs/research')
-rw-r--r--docs/research/140-spec-suite.md46
1 files changed, 46 insertions, 0 deletions
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). 위 표의 여덟 후보 가운데 무엇을 어떤 모양으로 받을지 정한다.