sx: step 13 — buffer primitives + buffer-based inspect

Added short aliases make-buffer / buffer? / buffer-append! / buffer->string /
buffer-length on both OCaml and JS hosts, sharing the existing StringBuffer
value type. buffer-append! auto-coerces non-strings via inspect.

Rewrote the OCaml host inspect function to walk a single shared Buffer.t
instead of allocating O(n) intermediate strings via String.concat at every
recursion level. inspect underlies sx-serialize and error-path formatting,
so this benefits the tightest serialization paths.

Median improvements (bin/bench_inspect.exe, best-of-3 of 9-run min):
  tree-d8 (75KB):    5.31ms -> 1.30ms  (-76%)
  tree-d10 (679KB): 81.89ms -> 16.02ms (-80%)
  dict-1000:         0.80ms -> 0.31ms  (-61%)
  list-2000:         0.74ms -> 0.33ms  (-55%)

Tests: OCaml 4545 -> 4550. JS 2591 -> 2596. Zero regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 02:16:59 +00:00
parent c48911e591
commit 0e022ab670
9 changed files with 303 additions and 67 deletions

View File

@@ -128,4 +128,37 @@
(string-buffer-append! buf sep)
(string-buffer-append! buf (first remaining))
(loop (rest remaining) " ")))
(assert= "the quick brown fox" (string-buffer->string buf)))))
(assert= "the quick brown fox" (string-buffer->string buf))))
(deftest
"make-buffer alias creates a buffer"
(let ((b (make-buffer))) (assert (buffer? b))))
(deftest
"buffer-append! with string"
(let ((b (make-buffer)))
(buffer-append! b "hello")
(buffer-append! b " ")
(buffer-append! b "world")
(assert= "hello world" (buffer->string b))))
(deftest
"buffer-append! coerces non-string values"
(let ((b (make-buffer)))
(buffer-append! b "n=")
(buffer-append! b 42)
(buffer-append! b ",")
(buffer-append! b true)
(buffer-append! b ",")
(buffer-append! b nil)
(assert= "n=42,true," (buffer->string b))))
(deftest
"buffer-length tracks total length"
(let ((b (make-buffer)))
(buffer-append! b "abc")
(buffer-append! b "de")
(assert= 5 (buffer-length b))))
(deftest
"buffer aliases interop with string-buffer"
(let ((b (make-buffer)))
(buffer-append! b "x")
(string-buffer-append! b "y")
(assert= "xy" (string-buffer->string b))
(assert= "xy" (buffer->string b)))))