Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jon Harrop <jon@ffconsultancy.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] function definition
Date: Sun, 21 Jan 2007 17:42:51 +0000	[thread overview]
Message-ID: <200701211742.51582.jon@ffconsultancy.com> (raw)
In-Reply-To: <45B36075.5000608@ujf-grenoble.fr>

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


  reply	other threads:[~2007-01-21 17:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-21 12:45 Vu Ngoc San
2007-01-21 17:42 ` Jon Harrop [this message]
2007-01-23 11:44   ` [Caml-list] " Vu Ngoc San

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200701211742.51582.jon@ffconsultancy.com \
    --to=jon@ffconsultancy.com \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox