unknown
2009-02-18 16:04:36 UTC
Pentium 4, 3.2 GHz
Windows XP
2.475 sec. -- F#
3.276 sec. -- Clojure (java -server)
5.921 sec. -- OCaml (ocamlopt)
5.156 sec. -- FreePascal
I included Pascal in order to show how the functional languages
compare to an imperative one.
It's amazing that F# and Clojure beat the machine language
generated by FreePascal.
F# -------------------------------------------------------------
let runs = 100
let max_iterations = 1000
let iterate ci cr =
let rec loop zi zr i =
if i <= max_iterations then
let
zr2 = zr * zr and
zi2 = zi * zi in
if zi2 + zr2 <= 4.0 then
loop ( zr * zi * 2.0 + ci) (zr2 - zi2 + cr) (i + 1)
else
i
else
0
in
loop 0.0 0.0 1
let mandelbrot n =
for y = -39 to 38 do
if 1 = n then printf "\n";
for x = -39 to 38 do
let i =
iterate (float x / 40.0) (float y / 40.0 - 0.5) in
if 1 = n then
printf "%s" ( if 0 = i then "*" else " " );
done
done;;
let timer = System.Diagnostics.Stopwatch.StartNew () in
for i = 1 to runs do
mandelbrot i
done;
printf "\n%d\n" timer.ElapsedMilliseconds;
Clojure -----------------------------------------------------
;; malkia's version
(def runs 100)
(def max_iterations 1000)
(defn iter [ci cr]
(let [max_iter (int max_iterations)
ci (double ci)
cr (double cr)]
(loop [zi (double ci) zr (double cr) i (int 1)]
(if (<= i max_iter)
(let [zr2 (* zr zr) zi2 (* zi zi)]
(if (<= (+ zr2 zi2) (double 4.0))
(recur (+ (* (* zr zi) (double 2.0)) ci)
(+ (- zr2 zi2) cr)
(inc i))
i))
0))))
(defn mand [n]
(doseq [y (range -39 39)]
(when (= 1 n) (print "\n"))
(doseq [x (range -39 39)]
(let [i (iter (/ x 40.0) (- (/ y 40.0) 0.5))]
(when (= 1 n) (print (if (= 0 i) "*" " ")))))))
(defn time-mand []
(time
(doseq [i (range 1 (inc runs))]
(mand i))))
(time-mand)
OCaml ---------------------------------------------
let runs = 100
let max_iterations = 1000
let iterate ci cr =
let bailout = 4.0 in
let rec loop zi zr i =
if i > max_iterations then
0
else
let temp = zr *. zi and
zr2 = zr *. zr and
zi2 = zi *. zi in
if zi2 +. zr2 > bailout then
i
else
loop (temp +. temp +. ci) (zr2 -. zi2 +. cr) (i + 1)
in
loop 0.0 0.0 1
let mandelbrot n =
for y = -39 to 38 do
if 1 = n then print_endline "" else ();
for x = -39 to 38 do
let i = iterate
(float x /. 40.0) (float y /. 40.0 -. 0.5) in
if 1 = n then
print_string ( if 0 = i then "*" else " " )
else ();
done
done;;
let start_time = Unix.gettimeofday () in
for iter = 1 to runs do
mandelbrot iter
done;
print_endline "";
print_float ( Unix.gettimeofday () -. start_time );
print_endline "";
FreePascal ----------------------------------------------------
uses sysutils; { for timing }
const
runs = 100;
max_iterations = 1000;
function iterate( ci, cr: real): longint;
var
count : longint;
zr, zi, zr2, zi2 : real;
begin
count := 1;
zr := 0.0; zi := 0.0; zr2 := 0.0; zi2 := 0.0;
while (count <= max_iterations) and (zr2 + zi2 < 4.0) do
begin
zi := zr * zi * 2.0 + ci;
zr := zr2 - zi2 + cr;
inc( count );
zr2 := zr * zr;
zi2 := zi * zi
end;
if count > max_iterations then
exit( 0 )
else
exit( count )
end;
procedure mandelbrot( n: longint );
var
y, x, i : longint;
begin
for y := -39 to 38 do
begin
if 1 = n then writeln;
for x := -39 to 38 do
begin
i := iterate( (x / 40.0), ( y / 40.0 - 0.5) );
if 1 = n then
if 0 = i then write( '*' ) else write( ' ' );
end
end
end;
var
when : tDateTime;
iter : longint;
begin
when := Time;
for iter := 1 to runs do
mandelbrot( iter );
writeln;
writeln( ((time - when) * secsPerDay):0:3, ' seconds' )
end.
Windows XP
2.475 sec. -- F#
3.276 sec. -- Clojure (java -server)
5.921 sec. -- OCaml (ocamlopt)
5.156 sec. -- FreePascal
I included Pascal in order to show how the functional languages
compare to an imperative one.
It's amazing that F# and Clojure beat the machine language
generated by FreePascal.
F# -------------------------------------------------------------
let runs = 100
let max_iterations = 1000
let iterate ci cr =
let rec loop zi zr i =
if i <= max_iterations then
let
zr2 = zr * zr and
zi2 = zi * zi in
if zi2 + zr2 <= 4.0 then
loop ( zr * zi * 2.0 + ci) (zr2 - zi2 + cr) (i + 1)
else
i
else
0
in
loop 0.0 0.0 1
let mandelbrot n =
for y = -39 to 38 do
if 1 = n then printf "\n";
for x = -39 to 38 do
let i =
iterate (float x / 40.0) (float y / 40.0 - 0.5) in
if 1 = n then
printf "%s" ( if 0 = i then "*" else " " );
done
done;;
let timer = System.Diagnostics.Stopwatch.StartNew () in
for i = 1 to runs do
mandelbrot i
done;
printf "\n%d\n" timer.ElapsedMilliseconds;
Clojure -----------------------------------------------------
;; malkia's version
(def runs 100)
(def max_iterations 1000)
(defn iter [ci cr]
(let [max_iter (int max_iterations)
ci (double ci)
cr (double cr)]
(loop [zi (double ci) zr (double cr) i (int 1)]
(if (<= i max_iter)
(let [zr2 (* zr zr) zi2 (* zi zi)]
(if (<= (+ zr2 zi2) (double 4.0))
(recur (+ (* (* zr zi) (double 2.0)) ci)
(+ (- zr2 zi2) cr)
(inc i))
i))
0))))
(defn mand [n]
(doseq [y (range -39 39)]
(when (= 1 n) (print "\n"))
(doseq [x (range -39 39)]
(let [i (iter (/ x 40.0) (- (/ y 40.0) 0.5))]
(when (= 1 n) (print (if (= 0 i) "*" " ")))))))
(defn time-mand []
(time
(doseq [i (range 1 (inc runs))]
(mand i))))
(time-mand)
OCaml ---------------------------------------------
let runs = 100
let max_iterations = 1000
let iterate ci cr =
let bailout = 4.0 in
let rec loop zi zr i =
if i > max_iterations then
0
else
let temp = zr *. zi and
zr2 = zr *. zr and
zi2 = zi *. zi in
if zi2 +. zr2 > bailout then
i
else
loop (temp +. temp +. ci) (zr2 -. zi2 +. cr) (i + 1)
in
loop 0.0 0.0 1
let mandelbrot n =
for y = -39 to 38 do
if 1 = n then print_endline "" else ();
for x = -39 to 38 do
let i = iterate
(float x /. 40.0) (float y /. 40.0 -. 0.5) in
if 1 = n then
print_string ( if 0 = i then "*" else " " )
else ();
done
done;;
let start_time = Unix.gettimeofday () in
for iter = 1 to runs do
mandelbrot iter
done;
print_endline "";
print_float ( Unix.gettimeofday () -. start_time );
print_endline "";
FreePascal ----------------------------------------------------
uses sysutils; { for timing }
const
runs = 100;
max_iterations = 1000;
function iterate( ci, cr: real): longint;
var
count : longint;
zr, zi, zr2, zi2 : real;
begin
count := 1;
zr := 0.0; zi := 0.0; zr2 := 0.0; zi2 := 0.0;
while (count <= max_iterations) and (zr2 + zi2 < 4.0) do
begin
zi := zr * zi * 2.0 + ci;
zr := zr2 - zi2 + cr;
inc( count );
zr2 := zr * zr;
zi2 := zi * zi
end;
if count > max_iterations then
exit( 0 )
else
exit( count )
end;
procedure mandelbrot( n: longint );
var
y, x, i : longint;
begin
for y := -39 to 38 do
begin
if 1 = n then writeln;
for x := -39 to 38 do
begin
i := iterate( (x / 40.0), ( y / 40.0 - 0.5) );
if 1 = n then
if 0 = i then write( '*' ) else write( ' ' );
end
end
end;
var
when : tDateTime;
iter : longint;
begin
when := Time;
for iter := 1 to runs do
mandelbrot( iter );
writeln;
writeln( ((time - when) * secsPerDay):0:3, ' seconds' )
end.