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>
47 lines
1.5 KiB
OCaml
47 lines
1.5 KiB
OCaml
(* Benchmark inspect on representative SX values.
|
|
Takes min of 9 runs of n iterations to dampen GC noise. *)
|
|
open Sx_types
|
|
|
|
let rec make_tree d =
|
|
if d = 0 then String "leaf"
|
|
else List [String "node"; make_tree (d - 1); make_tree (d - 1); make_tree (d - 1)]
|
|
|
|
let bench_min label f n runs =
|
|
let times = ref [] in
|
|
for _ = 1 to runs do
|
|
Gc.compact ();
|
|
let t0 = Unix.gettimeofday () in
|
|
for _ = 1 to n do ignore (f ()) done;
|
|
let t1 = Unix.gettimeofday () in
|
|
times := (t1 -. t0) :: !times
|
|
done;
|
|
let sorted = List.sort compare !times in
|
|
let min_t = List.nth sorted 0 in
|
|
let median = List.nth sorted (runs / 2) in
|
|
Printf.printf " %-30s min=%6.2fms median=%6.2fms (n=%d * %d runs)\n%!"
|
|
label (min_t *. 1000.0 /. float_of_int n)
|
|
(median *. 1000.0 /. float_of_int n) n runs
|
|
|
|
let () =
|
|
let tree8 = make_tree 8 in
|
|
let s = inspect tree8 in
|
|
Printf.printf "tree-d8 inspect len=%d\n%!" (String.length s);
|
|
bench_min "inspect tree-d8" (fun () -> inspect tree8) 50 9;
|
|
|
|
let tree10 = make_tree 10 in
|
|
let s = inspect tree10 in
|
|
Printf.printf "tree-d10 inspect len=%d\n%!" (String.length s);
|
|
bench_min "inspect tree-d10" (fun () -> inspect tree10) 5 9;
|
|
|
|
let dict_xs = make_dict () in
|
|
for i = 0 to 999 do
|
|
Hashtbl.replace dict_xs (string_of_int i) (Integer i)
|
|
done;
|
|
let d = Dict dict_xs in
|
|
bench_min "inspect dict-1000" (fun () -> inspect d) 100 9;
|
|
|
|
let xs = ref [] in
|
|
for i = 0 to 1999 do xs := Integer i :: !xs done;
|
|
let lst = List !xs in
|
|
bench_min "inspect list-2000" (fun () -> inspect lst) 200 9
|