Version française
Home     About     Download     Resources     Contact us    
Browse thread
an ocaml performance test
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Mark Hayden <hayden@c...>
Subject: an ocaml performance test


  Several months back I asked this mailing list
if anyone had any tests for gauging the
performance of basic operations in ocaml.  I got
some responses, but no data, so I put together a
test program, which I'm posting for others who
might be interested.  The tests are intended to
give a sense of relative costs of similar
operations within ocaml.  The output was
gathered by running the program on a
sparcstation 10 from Ocaml 1.01, compiled with
the "ocamlopt -unsafe".
  The numbers in the table are meaningless on
their own.  The test program below should also
be examined to see exactly what is being
measured.
  Many of the tests are straightforward to
interpret.  For example, it appears that
scanning an array with Array.iter is
considerably slow than with a for loop.  I'm not
sure, however, how to interpret the tests
measuring the performance of function
application to various kinds of closures (marked
"partial" in the table).  I have some guesses,
but I would appreciate an explanation from
someone who knows what is going on.

thanks, Mark Hayden


OUTPUT

                          null : 000.2958 usec

                         1 arg : 000.0782 usec
                         2 arg : 000.0978 usec
                         3 arg : 000.1236 usec
                       partial : 000.2286 usec
                    partial(a) : 000.2326 usec
                    partial(b) : 000.2247 usec
                    partial(c) : 000.0899 usec
                         magic : -00.0032 usec
                           let : -00.0001 usec
                          succ : 000.0140 usec
                   hashtbl:int : 002.5633 usec
                array:for:0000 : 000.1085 usec
           Array.iter:let:0000 : 000.3845 usec
           Array.iter:fun:0000 : 000.8096 usec
                array:for:0010 : 000.7928 usec
           Array.iter:let:0010 : 004.7812 usec
           Array.iter:fun:0010 : 005.4675 usec
               array:vect:1000 : 090.7683 usec
           Array.iter:let:1000 : 440.9373 usec
           Array.iter:fun:1000 : 453.8632 usec
             let rec list:1000 : 100.0212 usec
            List.iter:let:1000 : 307.8812 usec
            List.iter:fun:1000 : 312.9682 usec
                  gettimeofday : 011.4198 usec
                        select : 118.0977 usec



TESTPERF.ML:

open Printf

let i a = a 
let v0    = Array.create 0 () 
let v10   = Array.create 10 () 
let v1000 = Array.create 1000 () 
let l1000 = Array.to_list v1000 

let f1 a = a
let f2 a b = a 
let f3 a b c = a

let f2a = fun () -> fun () -> ()
let f2b = fun a -> fun b -> a
let f2c = fun a -> let c = () in fun b -> a

let f2p = f2 () 
let f2pa = f2a () 
let f2pb = f2b () 
let f2pc = f2c () 

let h = Hashtbl.create 10 
let hi = 234 
let hv = 123 
let _ = Hashtbl.add h hi hv 

let zero = 0.0 

let tests = [
  1E7, "null", i ; 

  1E6, "1 arg", 
    (fun () -> f1 ()) ;

  1E6, "2 arg", 
    (fun () -> f2 () ()) ;

  1E6, "3 arg", 
    (fun () -> f3 () () ()) ;

  1E6, "partial", 
    (fun () -> f2p ()) ;

  1E6, "partial(a)", 
    (fun () -> f2pa ()) ;

  1E6, "partial(b)", 
    (fun () -> f2pb ()) ;

  1E6, "partial(c)", 
    (fun () -> f2pc ()) ;

  1E6, "magic", 
    (fun () -> Obj.magic (Obj.repr ())) ;

  1E6, "let", 
    (fun () -> let a = () in a) ;

  1E6, "succ", 
    (fun () -> succ 5 ; ()) ;

  1E5, "hashtbl:int", 
    (fun () -> Hashtbl.find h hi ; ()) ;

  1E5, "array:for:0000", 
    (fun () -> for i = 0 to pred (Array.length v0) do () done) ;

  1E5, "Array.iter:let:0000", 
    (fun () -> Array.iter i v0) ;

  1E5, "Array.iter:fun:0000", 
    (fun () -> Array.iter (fun a -> a) v0) ;

  1E4, "array:for:0010", 
    (fun () -> for i = 0 to pred (Array.length v10) do () done) ;

  1E4, "Array.iter:let:0010", 
    (fun () -> Array.iter i v10) ;

  1E4, "Array.iter:fun:0010", 
    (fun () -> Array.iter (fun a -> a) v10) ;

  1E3, "array:for:1000", 
    (fun () -> for i = 0 to pred (Array.length v1000) do () done) ;

  1E3, "Array.iter:let:1000", 
    (fun () -> Array.iter i v1000) ;

  1E3, "Array.iter:fun:1000", 
    (fun () -> Array.iter (fun a -> a) v1000) ;

  1E3, "let rec list:1000",
    (fun () -> let rec loop = function [] -> () | hd::tl -> loop tl in loop l1000) ;

  1E3, "List.iter:let:1000", 
    (fun () -> List.iter i l1000) ;

  1E3, "List.iter:fun:1000", 
    (fun () -> List.iter (fun a -> a) l1000) ;

  1E4, "gettimeofday", 
    (fun () -> Unix.gettimeofday () ; ()) ;

  1E4, "select", 
    (fun () -> Unix.select [] [] [] zero ; ())
] 

let ntests = 1000 

let run () =
  let adjust = ref 0.0 in
  List.iter (fun (ntests,name,f) ->
    let ntests = truncate ntests in
    let start = Unix.gettimeofday () in
    for i = 1 to ntests do f () done ;
    let stop = Unix.gettimeofday () in
    let time = ((stop -. start) /. (float ntests)) *. 1000000.0 in
    printf "%30s : %08.4f usec\n" name (time -. !adjust) ;
    flush stdout ;
    if name = "null" then (
      adjust := time ;
      printf "\n"
    )
  ) tests

let _ = run () 

COMPILE

testperf: testperf.ml
	ocamlopt -unsafe -o testperf unix.cmxa testperf.ml -cclib -lunix