(* 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
