From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 80B8FBC0B for ; Sun, 21 Jan 2007 18:49:43 +0100 (CET) Received: from pih-relay06.plus.net (pih-relay06.plus.net [212.159.14.133]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l0LHng4r008411 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 21 Jan 2007 18:49:43 +0100 Received: from [80.229.56.224] (helo=[10.0.0.5]) by pih-relay06.plus.net with esmtp (Exim) id 1H8gp1-0003qE-Md for caml-list@yquem.inria.fr; Sun, 21 Jan 2007 17:49:39 +0000 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] function definition Date: Sun, 21 Jan 2007 17:42:51 +0000 User-Agent: KMail/1.9.5 References: <45B36075.5000608@ujf-grenoble.fr> In-Reply-To: <45B36075.5000608@ujf-grenoble.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200701211742.51582.jon@ffconsultancy.com> X-Miltered: at discorde with ID 45B3A7B6.002 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; binop:01 binop:01 ocamlopt:01 ocamlopt:01 inlined:01 ocaml:01 ocaml:01 frog:98 invoke:01 wrote:01 caml-list:01 matched:01 inline:01 closure:01 closure:01 On Sunday 21 January 2007 12:45, Vu Ngoc San wrote: > I'm sure this is a basic question: > > what is the difference between these ways of defining a function, and > what is the most efficient (I mean for the resulting function f = binop > o f1 f2, which typically will be called x*1000 times) That's a very hard question, and is probably platform specific but I'll throw some ideas at you off the top of my head. I'm sure someone like Brian Hurt will dive into the assembler and prove me wrong. ;-) > type operator = Plus | Minus;; > > > let binop1 o f1 f2 = > fun x -> match o with > | Plus -> (f1 x) +. (f2 x) > | Minus -> (f1 x) -. (f2 x) That is equivalent to: let binop1 o f1 f2 x = .. it waits for all arguments before doing anything. ocamlopt optimises currying for that case. > let binop2 o f1 f2 = > match o with > | Plus -> fun x -> (f1 x) +. (f2 x) > | Minus -> fun x -> (f1 x) -. (f2 x) After 3 args, this returns a closure waiting for the fourth arg. > let binop3 o f1 f2 = > let op = match o with > | Plus -> (+.) > | Minus -> (-.) in > fun x -> op (f1 x) (f2 x) After 3 args, this creates a closure to do the op and another closure that captures the first closure. ocamlopt might inline the closure "op" but I doubt it. > let binop4 o f1 f2 = > fun x -> > let op = match o with > | Plus -> (+.) > | Minus -> (-.) in > op (f1 x) (f2 x) This waits for all four args again (same as first case) and the closure "op" might be inlined. Assuming you invoke the function will all four arguments, I would expect the first solution to be the fastest by a significant margin. If you factor out a closure of binop with its first three arguments passed and use it multiple times then the second solution might be faster. I've found this with a pattern matcher written in OCaml that was faster when the pattern matcher evaluated when partially applied to the pattern, returning a closure that matched against the pattern it had been partially applied to. I was surprised to find that. I still don't know why that would be faster... -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. Objective CAML for Scientists http://www.ffconsultancy.com/products/ocaml_for_scientists