From 53d5a80b966a89e96cfa5996e0d112d625ae3108 Mon Sep 17 00:00:00 2001 From: Fabian Date: Sun, 19 Apr 2020 17:37:25 +0200 Subject: [PATCH] benchmark for memory usage of data structures --- benchs/dune | 8 +++--- benchs/objsize.ml | 14 +++++------ benchs/run_objsize.ml | 57 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 benchs/run_objsize.ml diff --git a/benchs/dune b/benchs/dune index 936b04c2..9a900f8d 100644 --- a/benchs/dune +++ b/benchs/dune @@ -1,11 +1,9 @@ - -(executables - (names run_benchs run_bench_hash) + (executables + (names run_benchs run_bench_hash run_objsize) (libraries containers containers.data containers.iter containers.thread benchmark gen iter qcheck oseq - batteries) + batteries base core_kernel sek) (flags :standard -warn-error -3 -safe-string -color always -open CCShims_) (ocamlopt_flags :standard -O3 -color always -unbox-closures -unbox-closures-factor 20) ) - diff --git a/benchs/objsize.ml b/benchs/objsize.ml index 668be91c..b05298cc 100644 --- a/benchs/objsize.ml +++ b/benchs/objsize.ml @@ -23,12 +23,12 @@ open Obj comparisons are done using physical equality. *) module H = Hashtbl.Make( - struct - type t = Obj.t - let equal = (==) + struct + type t = Obj.t + let equal = (==) let hash o = Hashtbl.hash (magic o : int) end) - + let node_table = (H.create 257 : unit H.t) let in_table o = try H.find node_table o; true with Not_found -> false @@ -53,15 +53,15 @@ let rec traverse t = if tag < no_scan_tag then begin count := !count + 1 + n; for i = 0 to n - 1 do - let f = field t i in + let f = field t i in if is_block f then traverse f done end else if tag = string_tag then - count := !count + 1 + n + count := !count + 1 + n else if tag = double_tag then count := !count + size_of_double else if tag = double_array_tag then - count := !count + 1 + size_of_double * n + count := !count + 1 + size_of_double * n else incr count end diff --git a/benchs/run_objsize.ml b/benchs/run_objsize.ml new file mode 100644 index 00000000..aa681623 --- /dev/null +++ b/benchs/run_objsize.ml @@ -0,0 +1,57 @@ +module Deque = Core_kernel.Deque +module Int_map = Map.Make(CCInt) +module Int_set = Set.Make(CCInt) + +let dup = CCPair.dup +let id = CCFun.id +let ns n = List.init n CCFun.id +let iter_range n f = List.iter f (ns n) + +let gen_cons x xs = + let saw_x = ref false in + fun () -> + if !saw_x then (saw_x := true; Some x) + else xs () + +let front = Sek.front +let dummy = 0 + +let types = [ + "Stdlib.List", (fun n -> Obj.magic @@ ns n); + "Stdlib.Array", (fun n -> Obj.magic @@ Array.init n id); + "Stdlib.Hashtbl", (fun n -> Obj.magic @@ Hashtbl.of_seq (OSeq.init ~n dup)); + "Base.Hashtbl", (fun n -> Obj.magic @@ Base.Hashtbl.Poly.of_alist_exn (List.init n dup)); + "Stdlib.Map", (fun n -> Obj.magic @@ Int_map.of_seq (OSeq.init ~n dup)); + "Stdlib.Set", (fun n -> Obj.magic @@ Int_set.of_seq (OSeq.init ~n id)); + "CCFun_vec", (fun n -> Obj.magic @@ CCFun_vec.of_list (ns n)); + "CCRAL", (fun n -> Obj.magic @@ CCRAL.of_list (ns n)); + "BatVect", (fun n -> Obj.magic @@ BatVect.of_list (ns n)); + "Sek.Persistent", (fun n -> Obj.magic @@ List.fold_left (Sek.Persistent.push front) (Sek.Persistent.create dummy) (ns n)); + "Sek.Ephemeral", (fun n -> Obj.magic @@ let c = Sek.Ephemeral.create dummy in iter_range n (Sek.Ephemeral.push front c); c); + "CCVector", (fun n -> Obj.magic @@ let c = CCVector.create () in iter_range n (CCVector.push c); c); + "Core_kernel.Deque", (fun n -> Obj.magic @@ let c = Deque.create () in iter_range n (Deque.enqueue_back c); c); + "Base.Queue", (fun n -> Obj.magic @@ let c = Base.Queue.create () in iter_range n (Base.Queue.enqueue c); c); + "Stdlib.Queue", (fun n -> Obj.magic @@ Queue.of_seq (OSeq.init ~n id)); + "CCQueue", (fun n -> Obj.magic @@ CCDeque.of_list (ns n)); + "Iter", (fun n -> Obj.magic @@ List.fold_right Iter.cons (ns n) Iter.empty); + "Gen", (fun n -> Obj.magic @@ List.fold_right gen_cons (ns n) Gen.empty); + "Stdlib.Seq", (fun n -> Obj.magic @@ List.fold_right OSeq.cons (ns n) OSeq.empty); +] + +let () = + let sizes = [0; 1; 10; 100; 1000; 10000] in + Printf.printf "%-20s " ""; + sizes |> List.iter (fun n -> Printf.printf "%6d " n); + Printf.printf "\n"; + types + |> List.iter (fun (name, create) -> + Printf.printf "%-20s: " name; + sizes + |> List.iter (fun n -> + let obj = create n in + let size = Objsize.size_w obj in + (* let size = Obj.reachable_words (Obj.repr obj) in *) + Printf.printf "%6d " size + ); + Printf.printf "\n" + )