(* done functionally, array mutation not used *)
(* speed on my machine 6.5 seconds for ocaml 3.10.2
8.9 seconds for Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Didn't try factor
*)
type point = Point of float * float * float
let makePoint n =
let fn = float_of_int n in
let x = sin fn in
let y = 3.0 *. cos fn in
let z =
let s = sin fn in
s *. s /. 2.0
in
Point(x,y,z)
;;
let toString (Point(x,y,z)) =
(string_of_float x) ^ "," ^
(string_of_float y) ^ "," ^
(string_of_float z)
;;
let makePoints n = Array.init n makePoint ;;
let pointNorm (Point(x,y,z)) = x *. x +. y *. y +. z *. z ;;
let normalizePoint (Point(x,y,z) as pt) =
let norm = pointNorm pt in
Point( x /. norm, y /. norm, z /. norm)
;;
let normalizePoints arr = Array.map normalizePoint arr ;;
let maxPoint (Point(x,y,z) as pt1) (Point(x2,y2,z2) as pt2) =
Point((max x x2), (max y y2), (max z z2))
;;
(* could throw an exception here but I don't care enough *)
let maxPoints arr =
Array.fold_left (fun max curr -> maxPoint max curr) arr.(0) arr
;;
let benchmark n =
print_endline (toString (maxPoints (normalizePoints (makePoints n))))
;;
let runBenchmark () =
(* Gc.compact (); *)
(* there is a GC lameness which makes consecutive runs slower, use time instead *)
(* for n = 1 to 8 do *)
print_string "Run #";
print_endline (string_of_int n);
let t1 = Sys.time () in
benchmark 5000000;
let t2 = Sys.time () in
print_endline ("Time: " ^ (string_of_float (t2 -. t1)));
(* done; *)
;;
runBenchmark();;