Paste: silly benchmark in OCaml, using mutation

Author: mfp
Mode: ml
Date: Sat, 29 Aug 2009 15:52:06
Plain Text |
(* solution using mutation
 *
 * on AMD64, 
 * 2.0 secs for OCaml 3.11.1
 *   (-nodynlink -inline 100, with OCAMLRUNPARAM=o=120,h=70M to set the heap size)
 * 8.3 secs for silly.java (java -Xms512m -server)
 *     Java HotSpot(TM) 64-Bit Server VM (build 10.0-b19, mixed mode)
 * *)

open Printf

type point = { mutable x : float; mutable y : float; mutable z : 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
    {x = x; y = y; z = z}

let toString p = sprintf "%f, %f, %f" p.x p.y p.z

let makePoints n = Array.init n makePoint

let pointNorm p = p.x *. p.x +. p.y *. p.y +. p.z *. p.z

let normalizePoint p =
  let norm = pointNorm p in
    p.x <- p.x /. norm;
    p.y <- p.y /. norm;
    p.z <- p.z /. norm

let normalizePoints arr = Array.iter normalizePoint arr; arr

let max (x : float) y = if x < y then y else x

let maxPoints arr =
  let m = { x = -2.; y = -2.; z = -2. } in
    Array.iter 
      (fun p -> m.x <- max m.x p.x; m.y <- max m.y p.y; m.z <- max m.z p.z) arr;
    m

let benchmark n = 
    print_endline (toString (maxPoints (normalizePoints (makePoints n))))

let runBenchmark () = 
  Gc.compact ();
  for n = 1 to 5 do
    printf "Run #%d\n%!" n;
    let t1 = Sys.time () in
      benchmark 5000000;
      let t2 = Sys.time () in
        printf "Time: %f\n%!" (t2 -. t1)
  done

let () = runBenchmark ()

New Annotation

Summary:
Author:
Mode:
Body: