From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id SAA04754 for caml-redistribution; Fri, 5 Jul 1996 18:06:01 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id IAA24093 for ; Thu, 4 Jul 1996 08:55:54 +0200 Received: from simon.cs.cornell.edu (SIMON.CS.CORNELL.EDU [128.84.154.10]) by concorde.inria.fr (8.7.1/8.7.1) with SMTP id IAA10006 for ; Thu, 4 Jul 1996 08:55:54 +0200 (MET DST) Received: from cloyd.cs.cornell.edu (CLOYD.CS.CORNELL.EDU [128.84.227.15]) by simon.cs.cornell.edu (8.6.10/R1.4) with ESMTP id CAA12356 for ; Thu, 4 Jul 1996 02:55:52 -0400 Received: from verdandi.cs.cornell.edu (VERDANDI.CS.CORNELL.EDU [128.84.254.202]) by cloyd.cs.cornell.edu (8.6.10/M1.8) with ESMTP id CAA24871; Thu, 4 Jul 1996 02:55:47 -0400 Received: (hayden@localhost) by verdandi.cs.cornell.edu (8.6.10/C1.3) id CAA13173; Thu, 4 Jul 1996 02:55:45 -0400 Date: Thu, 4 Jul 1996 02:55:45 -0400 Message-Id: <199607040655.CAA13173@verdandi.cs.cornell.edu> From: Mark Hayden To: caml-list@pauillac.inria.fr cc: hayden@cs.cornell.edu Subject: an ocaml performance test Sender: weis 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