Re: [Camllist] generic Hashtbl.to_array
 Christoph Bauer
[
Home
]
[ Index:
by date

by threads
]
[ Message by date: previous  next ] [ Message in thread: previous  next ] [ Thread: previous  next ]
[ Message by date: previous  next ] [ Message in thread: previous  next ] [ Thread: previous  next ]
Date:  20060725 (12:01) 
From:  Christoph Bauer <christoph.bauer@l...> 
Subject:  Re: [Camllist] generic Hashtbl.to_array 
Hi, > let to_array t = > let init = ref None in > begin try Hashtbl.iter (fun k v > init := Some (k,v); > raise Exit) t > with Exit > () > end; > match !init with >  None > [ ] >  Some i > > let a = Array.make (Hashtbl.length t) i in > ignore (Hashtbl.fold (fun k v i > a.(i) < (k, v); i + 1) t 0); > a > ;; it's curious, but this solution is slower than the others! [skaller's solution seems to be the same, so I include only this one in the "benchmark"] Rate to_array_4 to_array_3 to_array_1b to_array_2 to_array_1 to_array_4 407+0/s  16% 16% 17% 17% to_array_3 486+2/s 19%  [0%] [1%] 1% to_array_1b 487+0/s 20% [0%]  [0%] 1% to_array_2 489+2/s 20% [1%] [0%]  1% to_array_1 491+0/s 21% 1% 1% 1%  from http://ocamlbenchmark.sourceforge.net/doc/Benchmark.html Benchmark.tablulate results prints a comparison table for a list of results obtained by Benchmark.latencyN or Benchmark.throughputN with each function compared to all the others. The table is of the type Rate name1 name2 ... OR s/iter name1 name2 ... name1 #/s  r12 name1 #  r12 name2 #/s r21  name2 # r21  ... ... where name1, name2,... are the labels of the tests sorted from slowest to fastest and rij says how much namei is faster (or slower if < 0) than namej (technically it is equal to (ri  rj) expressed in percents of rj where ri and rj are the rates of namei and namej respectively). If several results are associated to a given name, they are used to compute a Student's statistic to check whether the rates are significantly different. If ri and rj are not believed to be different, rij will be printed between brackets. (* compile with ocamlopt o to_array I benchmark0.7 unix.cmxa benchmark0.7/benchmark.cmx to_array.ml *) open Benchmark let to_array_1 t = let dummy = Array.init 0 (fun _ > raise Not_found) in fst (Hashtbl.fold (fun k v (a, i) > if i = 0 then let a = Array.make (Hashtbl.length t) (k, v) in (a, 0) else (a.(i) < (k, v); (a, i + 1))) t (dummy, 0)) let to_array_2 t = let init _ = fun () > raise Not_found in let a = Array.init (Hashtbl.length t) init in ignore (Hashtbl.fold (fun k v i > a.(i) < (fun () > (k, v)); i+1) t 0); Array.map (fun f > f ()) a let to_array_3 t = Array.of_list (Hashtbl.fold (fun a b c > (a, b) :: c) t []) let to_array_1b t = let a = ref (Array.init 0 (fun _ > raise Not_found)) in ignore (Hashtbl.fold (fun k v i > if i = 0 then (a := Array.make (Hashtbl.length t) (k, v); i) else ((!a).(i) < (k, v); i + 1)) t 0); !a let to_array_4 t = let init = ref None in begin try Hashtbl.iter (fun k v > init := Some (k,v); raise Exit) t with Exit > () end; match !init with  None > [ ]  Some i > let a = Array.make (Hashtbl.length t) i in ignore (Hashtbl.fold (fun k v i > a.(i) < (k, v); i + 1) t 0); a let h () = let h = Hashtbl.create 100000 in for i = 0 to (Hashtbl.length h) do Hashtbl.add h (Random.int max_int) (Random.int max_int); done; h let main () = let h = h () in let res = throughputN ~repeat:5 1 [("to_array_1", to_array_1, h); ("to_array_1b", to_array_1b, h); ("to_array_2", to_array_2, h); ("to_array_3", to_array_3, h); ("to_array_4", to_array_4, h); ] in tabulate res let () = main ()