[Shootout-list] Improved Ocaml Mandlebrot

Brian Hurt bhurt at spnz.org
Tue Aug 23 01:43:32 UTC 2005


Attached is a speed-improved version of Mandlebrot in Ocaml.  It runs in 
about 3/4th to 2/3rds the time on my machine.  Humorously enough, the 
changes make the program more functional in nature, as I changed a for 
loop with references to a recursive function.  Someone should probably 
check to make sure the output is correct before including it.

Brian
-------------- next part --------------
let niter = 50
let limit = 2.

let limit2 = limit *. limit

type complex = { mutable r:float; mutable i:float }

let get_bit c z =
  z.r <- 0.;
  z.i <- 0.;
  let rec loop i =
     if i < niter then
      begin
        let zi = 2. *. z.r *. z.i +. c.i in
        z.r <- z.r *. z.r -. z.i *. z.i +. c.r;
        z.i <- zi;
        if z.r *. z.r +. z.i *. z.i > limit2 then false else loop (i+1)
      end
    else
      true
  in
  loop 0

let () =
  let w = int_of_string(Array.get Sys.argv 1) in
  let h = w in
  let fw = float w
  and fh = float h
  and cplmt8 = 8 - w mod 8 in
  Printf.printf "P4\n%i %i\n" w h;
  let c = { r = 0.0; i = 0.0 } in
  let tmp = { r = 0.0; i = 0.0 } in

  let rec loop1 byte bit y x =
    c.i <- 2. *. float y /. fh -. 1.;
    c.r <- 2. *. float x /. fw -. 1.5;
    let byte =
      if get_bit c tmp then
         (byte lsl 1) lor 1
      else
         byte lsl 1
    in
    loop2 byte (bit + 1) y x
  and loop2 byte bit y x =
     if bit == 8 then
        begin
          output_byte stdout byte;
          loop3 0 0 y x
        end
     else
        loop3 byte bit y x
  and loop3 byte bit y x =
    let x = x + 1 in
    if (x == w) then
      let y = y + 1 in
      if (y == h) then
        begin
          output_byte stdout byte;
          ()
        end
      else
        loop1 byte bit y 0
    else
      loop1 byte bit y x
  in
  loop1 0 0 0 0


More information about the Shootout-list mailing list