caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] is there a more concise way to write this?
@ 2012-01-20  6:38 Martin DeMello
  2012-01-20  6:46 ` Valentin ROBERT
                   ` (3 more replies)
  0 siblings, 4 replies; 27+ messages in thread
From: Martin DeMello @ 2012-01-20  6:38 UTC (permalink / raw)
  To: OCaml List

      let a = match (out, value) with
        (true, true)  -> [o; v]
      | (false, true) -> [v]
      | (true, false) -> [o]
      | (false, false) -> []

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:38 [Caml-list] is there a more concise way to write this? Martin DeMello
@ 2012-01-20  6:46 ` Valentin ROBERT
  2012-01-20  6:58   ` Martin DeMello
                     ` (2 more replies)
  2012-01-20  8:52 ` Lin
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 27+ messages in thread
From: Valentin ROBERT @ 2012-01-20  6:46 UTC (permalink / raw)
  To: Martin DeMello; +Cc: OCaml List

[-- Attachment #1: Type: text/plain, Size: 733 bytes --]

I guess you can write it like:

let a = (if out then [o] else []) @ (if value then [v] else [])

But it's not particularly more pleasant to the eye.
Still it reduces the exponential explosion of the code, at a small
additional cost (the @), I believe.

On Fri, Jan 20, 2012 at 07:38, Martin DeMello <martindemello@gmail.com>wrote:

>      let a = match (out, value) with
>        (true, true)  -> [o; v]
>      | (false, true) -> [v]
>      | (true, false) -> [o]
>      | (false, false) -> []
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>

[-- Attachment #2: Type: text/html, Size: 1388 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:46 ` Valentin ROBERT
@ 2012-01-20  6:58   ` Martin DeMello
  2012-01-20  8:37   ` David Allsopp
  2012-01-20  8:37   ` Sebastien Ferre
  2 siblings, 0 replies; 27+ messages in thread
From: Martin DeMello @ 2012-01-20  6:58 UTC (permalink / raw)
  To: Valentin ROBERT; +Cc: OCaml List

thanks, that does reduce the potential explosion, which was my main
concern. it even looks pleasant enough if you add a linebreak in the
middle.

martin

On Thu, Jan 19, 2012 at 10:46 PM, Valentin ROBERT
<valentin.robert.42@gmail.com> wrote:
> I guess you can write it like:
>
> let a = (if out then [o] else []) @ (if value then [v] else [])
>
> But it's not particularly more pleasant to the eye.
> Still it reduces the exponential explosion of the code, at a small
> additional cost (the @), I believe.
>
> On Fri, Jan 20, 2012 at 07:38, Martin DeMello <martindemello@gmail.com>
> wrote:
>>
>>      let a = match (out, value) with
>>        (true, true)  -> [o; v]
>>      | (false, true) -> [v]
>>      | (true, false) -> [o]
>>      | (false, false) -> []
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa-roc.inria.fr/wws/info/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:46 ` Valentin ROBERT
  2012-01-20  6:58   ` Martin DeMello
@ 2012-01-20  8:37   ` David Allsopp
  2012-01-20 13:29     ` Edgar Friendly
  2012-01-20  8:37   ` Sebastien Ferre
  2 siblings, 1 reply; 27+ messages in thread
From: David Allsopp @ 2012-01-20  8:37 UTC (permalink / raw)
  To: Valentin ROBERT, Martin DeMello; +Cc: OCaml List

Valentin ROBERT wrote:
> I guess you can write it like:
> 
> let a = (if out then [o] else []) @ (if value then [v] else [])
>
> But it's not particularly more pleasant to the eye.
> Still it reduces the exponential explosion of the code, at a small additional cost (the @), I believe.

Actually, it's possible that with more cases it might be faster - it's eliminating the allocation (at some point) of all the tuples needed for the match case, it potentially eliminates a lot of linear comparisons to find the correct match case (I don't think that the compiler would be able to optimise that to a hash-based or index-based lookup) and [@]'s running time is proportional to the length of its first argument only - which here is always a singleton or empty list. The only extra cost is in space - you allocate a cons cell for each item which is included in the list twice (once to put it in the singleton list and once to append the rest of the list to it).

If the actual scenario is lots more of these put together, you could profitably define a better special-case operator:

let (@@) a b = match a with [] -> b | [a] -> a::b | _ -> assert false

(a dirty - though still safe - solution with Obj.magic can reduce the [match] to an [if]...)


David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:46 ` Valentin ROBERT
  2012-01-20  6:58   ` Martin DeMello
  2012-01-20  8:37   ` David Allsopp
@ 2012-01-20  8:37   ` Sebastien Ferre
  2012-01-20  9:11     ` Jerome Vouillon
  2 siblings, 1 reply; 27+ messages in thread
From: Sebastien Ferre @ 2012-01-20  8:37 UTC (permalink / raw)
  To: caml-list

Hi,

On 01/20/2012 07:46 AM, Valentin ROBERT wrote:
> I guess you can write it like:
>
> let a = (if out then [o] else []) @ (if value then [v] else [])
>
> But it's not particularly more pleasant to the eye.
> Still it reduces the exponential explosion of the code, at a small
> additional cost (the @), I believe.

You can make it even more concise by defining a helping function.

let b2l b x = if b then [x] else [];;

let a =
   b2l out o @
   b2l value v;;

This easily generalizes to an arbitrary number of boolean variables.

---
Sébastien Ferré


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:38 [Caml-list] is there a more concise way to write this? Martin DeMello
  2012-01-20  6:46 ` Valentin ROBERT
@ 2012-01-20  8:52 ` Lin
  2012-01-20  9:08   ` Valentin ROBERT
  2012-01-20  9:38 ` oliver
  2012-01-20 20:40 ` oliver
  3 siblings, 1 reply; 27+ messages in thread
From: Lin @ 2012-01-20  8:52 UTC (permalink / raw)
  To: caml-list

What about:

let a = List.filter (fun x -> x)  [out; value]

Lin


On 01/20/2012 02:38 PM, Martin DeMello wrote:
>        let a = match (out, value) with
>          (true, true)  ->  [o; v]
>        | (false, true) ->  [v]
>        | (true, false) ->  [o]
>        | (false, false) ->  []
>



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  8:52 ` Lin
@ 2012-01-20  9:08   ` Valentin ROBERT
  2012-01-20  9:19     ` Lin
  2012-01-20 10:21     ` Martin DeMello
  0 siblings, 2 replies; 27+ messages in thread
From: Valentin ROBERT @ 2012-01-20  9:08 UTC (permalink / raw)
  To: Lin; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 874 bytes --]

Rather (in this case):

let a = List.map fst (List.filter (fun x -> snd x) [(out, o); (value, v)])

That seems reasonable.

On Fri, Jan 20, 2012 at 09:52, Lin <mysnowls@163.com> wrote:

> What about:
>
> let a = List.filter (fun x -> x)  [out; value]
>
> Lin
>
>
>
> On 01/20/2012 02:38 PM, Martin DeMello wrote:
>
>>       let a = match (out, value) with
>>         (true, true)  ->  [o; v]
>>       | (false, true) ->  [v]
>>       | (true, false) ->  [o]
>>       | (false, false) ->  []
>>
>>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/**wws/info/caml-list<https://sympa-roc.inria.fr/wws/info/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>
>

[-- Attachment #2: Type: text/html, Size: 1595 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  8:37   ` Sebastien Ferre
@ 2012-01-20  9:11     ` Jerome Vouillon
  2012-01-20  9:34       ` Fabrice Le Fessant
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Vouillon @ 2012-01-20  9:11 UTC (permalink / raw)
  To: Sebastien Ferre; +Cc: caml-list

On Fri, Jan 20, 2012 at 09:37:17AM +0100, Sebastien Ferre wrote:
> You can make it even more concise by defining a helping function.
> 
> let b2l b x = if b then [x] else [];;
> 
> let a =
>   b2l out o @
>   b2l value v;;

You can also include the list concatenation in the helper function:

    let maybe b v c = if b then v :: c else c
    let g out o value v = maybe out o (maybe value v [])

And the parentheses can be avoided by using a right associative
application operator:

    let (@@) f x = f x
    let a = maybe out o @@ maybe value v @@ []

-- Jerome

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  9:08   ` Valentin ROBERT
@ 2012-01-20  9:19     ` Lin
  2012-01-20 10:21     ` Martin DeMello
  1 sibling, 0 replies; 27+ messages in thread
From: Lin @ 2012-01-20  9:19 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 1138 bytes --]

Oh sorry I assumed `o' is short for `out' and `v' for `value', which 
seems not the case.

By the way, in your solution  `fst' and `snd' should be exchanged, i.e.

let a = List.map snd (List.filter (fun x -> fst x) [(out, o); (value, v)])


On 01/20/2012 05:08 PM, Valentin ROBERT wrote:
> Rather (in this case):
>
> let a = List.map fst (List.filter (fun x -> snd x) [(out, o); (value, v)])
>
> That seems reasonable.
>
> On Fri, Jan 20, 2012 at 09:52, Lin <mysnowls@163.com 
> <mailto:mysnowls@163.com>> wrote:
>
>     What about:
>
>     let a = List.filter (fun x -> x)  [out; value]
>
>     Lin
>
>
>
>     On 01/20/2012 02:38 PM, Martin DeMello wrote:
>
>               let a = match (out, value) with
>                 (true, true)  ->  [o; v]
>               | (false, true) ->  [v]
>               | (true, false) ->  [o]
>               | (false, false) ->  []
>
>
>
>
>     -- 
>     Caml-list mailing list.  Subscription management and archives:
>     https://sympa-roc.inria.fr/wws/info/caml-list
>     Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>     Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


[-- Attachment #2: Type: text/html, Size: 3206 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  9:11     ` Jerome Vouillon
@ 2012-01-20  9:34       ` Fabrice Le Fessant
  2012-01-20 10:27         ` Arnaud Spiwack
  0 siblings, 1 reply; 27+ messages in thread
From: Fabrice Le Fessant @ 2012-01-20  9:34 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 602 bytes --]

On 01/20/2012 10:11 AM, Jerome Vouillon wrote:
> And the parentheses can be avoided by using a right associative
> application operator:
>
>     let (@@) f x = f x
>     let a = maybe out o @@ maybe value v @@ []

Since the "%revapply" primitive is available in SVN 3.12 (next 3.12.2 or
3.13), you will be able to use "pipes", without the penalty of expensive
partial applications:

external ( |> ) : 'a -> ('a -> 'b) -> 'b = "%revapply"

let a = [] |> maybe value v |> maybe out o

I am wondering now if we should also provide the "%apply" primitive too,
to be able to choose the order...

--Fabrice


[-- Attachment #2: fabrice_le_fessant.vcf --]
[-- Type: text/x-vcard, Size: 380 bytes --]

begin:vcard
fn:Fabrice LE FESSANT
n:LE FESSANT;Fabrice
org:INRIA Saclay -- Ile-de-France;P2P & OCaml
adr;quoted-printable:;;Parc Orsay Universit=C3=A9 ;Orsay CEDEX;;91893;France
email;internet:fabrice.le_fessant@inria.fr
title;quoted-printable:Charg=C3=A9 de Recherche
tel;work:+33 1 74 85 42 14
tel;fax:+33 1 74 85 42 49 
url:http://fabrice.lefessant.net/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:38 [Caml-list] is there a more concise way to write this? Martin DeMello
  2012-01-20  6:46 ` Valentin ROBERT
  2012-01-20  8:52 ` Lin
@ 2012-01-20  9:38 ` oliver
  2012-01-20 13:59   ` Edgar Friendly
  2012-01-20 20:40 ` oliver
  3 siblings, 1 reply; 27+ messages in thread
From: oliver @ 2012-01-20  9:38 UTC (permalink / raw)
  To: Martin DeMello; +Cc: OCaml List

Hello,

On Thu, Jan 19, 2012 at 10:38:53PM -0800, Martin DeMello wrote:
>       let a = match (out, value) with
>         (true, true)  -> [o; v]
>       | (false, true) -> [v]
>       | (true, false) -> [o]
>       | (false, false) -> []

The code looks fine for me.

More concise does not always mean better readable or more performant.
You apply the same kind of selection for both values.

Something that would aequivalent would be of type 'a option.
But I doubt that using option type here would make it more concise.

Would it make it Better readable? Not necessarily.

But at least it would show the operation more clear.

But not sure if you want to handle option type in your result.

I think a fold could do the selection of the raw values afterwards.

If out is derived from o and v is derived from v and both are selected
by the same function, you could use that function inside a fold.
But would that really be more readable?
It might be more generic.
But if both selections are not done by the same function application to your
result values, this also does not make sense.

Do you see what I mean?

Ciao,
   Oliver

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  9:08   ` Valentin ROBERT
  2012-01-20  9:19     ` Lin
@ 2012-01-20 10:21     ` Martin DeMello
  1 sibling, 0 replies; 27+ messages in thread
From: Martin DeMello @ 2012-01-20 10:21 UTC (permalink / raw)
  To: Valentin ROBERT; +Cc: Lin, caml-list

I ended up using

  let (>>?) x y = if x then [y] else [] in
  let a = (out   >>? ...) @
            (value >>? ...)

which had the advantage that it let me inline the definitions of o and
v while keeping things readable.

martin

On Fri, Jan 20, 2012 at 1:08 AM, Valentin ROBERT
<valentin.robert.42@gmail.com> wrote:
> Rather (in this case):
>
> let a = List.map fst (List.filter (fun x -> snd x) [(out, o); (value, v)])
>
> That seems reasonable.
>
>
> On Fri, Jan 20, 2012 at 09:52, Lin <mysnowls@163.com> wrote:
>>
>> What about:
>>
>> let a = List.filter (fun x -> x)  [out; value]
>>
>> Lin
>>
>>
>>
>> On 01/20/2012 02:38 PM, Martin DeMello wrote:
>>>
>>>       let a = match (out, value) with
>>>         (true, true)  ->  [o; v]
>>>       | (false, true) ->  [v]
>>>       | (true, false) ->  [o]
>>>       | (false, false) ->  []
>>>
>>
>>
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa-roc.inria.fr/wws/info/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  9:34       ` Fabrice Le Fessant
@ 2012-01-20 10:27         ` Arnaud Spiwack
  0 siblings, 0 replies; 27+ messages in thread
From: Arnaud Spiwack @ 2012-01-20 10:27 UTC (permalink / raw)
  To: Fabrice Le Fessant; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 284 bytes --]

> I am wondering now if we should also provide the "%apply" primitive too,
> to be able to choose the order...
>

The ability to choose the order seems quite valuable to me. Plus, there is
a right-associative apply in the non-rev order in Ocaml's distribution
(namely in ocamlbuild).

[-- Attachment #2: Type: text/html, Size: 479 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  8:37   ` David Allsopp
@ 2012-01-20 13:29     ` Edgar Friendly
  2012-01-20 13:50       ` Fabrice Le Fessant
                         ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Edgar Friendly @ 2012-01-20 13:29 UTC (permalink / raw)
  To: caml-list

On 01/20/2012 03:37 AM, David Allsopp wrote:
> Actually, it's possible that with more cases it might be faster -
> it's
> eliminating the allocation (at some point) of all the tuples needed for
> the match case,

Doesn't the ocaml compiler not allocate the unnecessary tuples? 
https://ocaml.janestreet.com/?q=node/90

> it potentially eliminates a lot of linear comparisons to
> find the correct match case (I don't think that the compiler would be
> able to optimise that to a hash-based or index-based lookup)

Isn't the compiler's compilation strategy for match cases able to build 
an optimized tree of comparisons in cases like this?  I agree there's no 
easy index or hash strategy for this, but I'd expect it to turn this 
pattern matching into the equivalent of:

if a then if b then [a;b] else [a]
else if b then [b] else []

E.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:29     ` Edgar Friendly
@ 2012-01-20 13:50       ` Fabrice Le Fessant
  2012-01-20 13:58       ` oliver
  2012-01-20 14:12       ` David Allsopp
  2 siblings, 0 replies; 27+ messages in thread
From: Fabrice Le Fessant @ 2012-01-20 13:50 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Fri, Jan 20, 2012 at 2:29 PM, Edgar Friendly <thelema314@gmail.com> wrote:
>> it potentially eliminates a lot of linear comparisons to
>> find the correct match case (I don't think that the compiler would be
>> able to optimise that to a hash-based or index-based lookup)
>
>
> Isn't the compiler's compilation strategy for match cases able to build an
> optimized tree of comparisons in cases like this?  I agree there's no easy
> index or hash strategy for this, but I'd expect it to turn this pattern
> matching into the equivalent of:
>
> if a then if b then [a;b] else [a]
> else if b then [b] else []

Indeed, the four line pattern-matching is turned into two consecutive
tests. In many cases, the pattern-matching compiler only generates the
optimal number of tests, so never be scared of creating big complex
patterns...

Regards,
Fabrice


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:29     ` Edgar Friendly
  2012-01-20 13:50       ` Fabrice Le Fessant
@ 2012-01-20 13:58       ` oliver
  2012-01-20 14:05         ` Edgar Friendly
  2012-01-20 14:12       ` David Allsopp
  2 siblings, 1 reply; 27+ messages in thread
From: oliver @ 2012-01-20 13:58 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Fri, Jan 20, 2012 at 08:29:09AM -0500, Edgar Friendly wrote:
[...]
> if a then if b then [a;b] else [a]
> else if b then [b] else []
[...]

For me, the original pattern matching code looks much easier to read.


Ciao,
   Oliver


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  9:38 ` oliver
@ 2012-01-20 13:59   ` Edgar Friendly
  2012-01-20 14:42     ` oliver
                       ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Edgar Friendly @ 2012-01-20 13:59 UTC (permalink / raw)
  To: caml-list

On 01/20/2012 04:38 AM, oliver wrote:
> More concise does not always mean better readable or more performant.
> You apply the same kind of selection for both values.

I can't measure readability, but I did throw together a quick benchmark 
to test the different methods.  Please take no offense at this - I'm 
sure that the responses were headed much more towards readability than 
performance, so comparing them on performance is totally unfair, and 
this in no way judges the people whose names I've used to label the 
solutions.

Maybe not surprisingly, the original match-based code came out fastest, 
and List.filter the slowest.

Here's the result summary:
demello (83.95 ns) is probably (alpha=7.88%) same speed as
friendly (88.68 ns) which is probably (alpha=23.96%) same speed as
vuillion (96.68 ns) which is 34.6% faster than
robert (147.94 ns) which is probably (alpha=8.43%) same speed as
ferre (154.63 ns) which is 70.7% faster than
lin (527.64 ns) which is 17.1% faster than
lefessant (636.43 ns) which is 31.1% faster than
lin2 (924.24 ns)

Source code and full results follow.

E.

---------------------------------

let o = 1 and v = 2

let demello = function
   | (true, true)  -> [o; v]
   | (false, true) -> [v]
   | (true, false) -> [o]
   | (false, false) -> []

let robert (out, value) =
   (if out then [o] else []) @ (if value then [v] else [])

let b2l b x = if b then [x] else [];;

let ferre (out, value) =
   b2l out o @
   b2l value v;;

let maybe b v c = if b then v :: c else c
let vuillion (out, value) = maybe out o (maybe value v [])

let (|>) x f = f x (* no %revapply yet *)
let lefessant (out, value) = [] |> maybe value v |> maybe out o

let lin (out, value) = List.filter (fun x -> x)  [out; value]
let lin2 (out, value) = List.map snd (List.filter (fun x -> fst x) 
[(out, o); (value, v)])

let friendly (out,value) =
   if out then if value then [o;v] else [o]
   else if value then [v] else []

let test f n =
   for i = 1 to n do
     ignore(f (true, true));
     ignore(f (true, false));
     ignore(f (false, true));
     ignore(f (false, false));
   done

let () = Bench.bench_n [
   "demello", test demello;
   "robert", test robert;
   "ferre", test ferre;
   "vuillion", test vuillion;
   "lefessant", test lefessant;
   "lin", test lin;
   "lin2", test lin2;
   "friendly", test friendly;
] |> Bench.summarize ~alpha:0.05

------------------------------

Measuring: System Clock
Warming up
Estimating clock resolution (1.44 us)
Estimating cost of timer call (1.60 us)
Benchmarking: demello
Ran 32768 iterations in 1.68 ms
Collecting 300 samples, 28127 iterations each, estimated time: 431.61 ms
N: 300 Inter-quartile width:16.65 ns, Full range: (43.99 ns,525.38 ns)
Outliers: 7 (2.3%) High Mild, 19 (6.3%) High Severe,
mean: 83.95 ns, 95% CI: (75.16 ns, 88.32 ns)
std.dev.: 48.91 ns, 95% CI: (27.18 ns, 61.20 ns)

Benchmarking: robert
Ran 16384 iterations in 2.96 ms
Collecting 300 samples, 7956 iterations each, estimated time: 431.66 ms
N: 300 Inter-quartile width:19.52 ns, Full range: (102.86 ns,644.99 ns)
Outliers: 6 (2.0%) High Mild, 9 (3.0%) High Severe,
mean: 147.94 ns, 95% CI: (141.11 ns, 153.17 ns)
std.dev.: 53.76 ns, 95% CI: (22.29 ns, 68.36 ns)

Benchmarking: ferre
Ran 16384 iterations in 2.71 ms
Collecting 300 samples, 8683 iterations each, estimated time: 431.64 ms
N: 300 Inter-quartile width:25.01 ns, Full range: (104.02 ns,795.03 ns)
Outliers: 6 (2.0%) High Mild, 11 (3.7%) High Severe,
mean: 154.63 ns, 95% CI: (149.85 ns, 168.24 ns)
std.dev.: 64.76 ns, 95% CI: (46.73 ns, 100.11 ns)

Benchmarking: vuillion
Ran 32768 iterations in 8.24 ms
Collecting 300 samples, 5724 iterations each, estimated time: 431.66 ms
N: 300 Inter-quartile width:26.91 ns, Full range: (38.71 ns,1.60 us)
Outliers: 14 (4.7%) High Severe,
mean: 96.68 ns, 95% CI: (72.67 ns, 115.55 ns)
std.dev.: 193.29 ns, 95% CI: (99.28 ns, 244.72 ns)

Benchmarking: lefessant
Ran 4096 iterations in 2.32 ms
Collecting 300 samples, 2543 iterations each, estimated time: 431.72 ms
N: 300 Inter-quartile width:147.38 ns, Full range: (346.26 ns,4.15 us)
Outliers: 3 (1.0%) High Severe,
mean: 636.43 ns, 95% CI: (602.68 ns, 664.49 ns)
std.dev.: 277.24 ns, 95% CI: (114.65 ns, 400.85 ns)

Benchmarking: lin
Ran 4096 iterations in 2.04 ms
Collecting 300 samples, 2891 iterations each, estimated time: 431.73 ms
N: 300 Inter-quartile width:190.01 ns, Full range: (305.90 ns,1.86 us)
Outliers: 2 (0.7%) High Severe,
mean: 527.64 ns, 95% CI: (514.62 ns, 556.02 ns)
std.dev.: 152.73 ns, 95% CI: (117.57 ns, 225.48 ns)

Benchmarking: lin2
Ran 4096 iterations in 2.49 ms
Collecting 300 samples, 2371 iterations each, estimated time: 431.71 ms
N: 300 Inter-quartile width:252.57 ns, Full range: (505.02 ns,5.90 us)
Outliers: 10 (3.3%) High Severe,
mean: 924.24 ns, 95% CI: (863.30 ns, 973.78 ns)
std.dev.: 469.52 ns, 95% CI: (247.89 ns, 617.19 ns)

Benchmarking: friendly
Ran 16384 iterations in 1.49 ms
Collecting 300 samples, 15769 iterations each, estimated time: 431.63 ms
N: 300 Inter-quartile width:15.57 ns, Full range: (49.11 ns,480.53 ns)
Outliers: 10 (3.3%) Low Mild, 6 (2.0%) High Severe,
mean: 88.68 ns, 95% CI: (86.37 ns, 94.85 ns)
std.dev.: 31.12 ns, 95% CI: (13.41 ns, 44.10 ns)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:58       ` oliver
@ 2012-01-20 14:05         ` Edgar Friendly
  0 siblings, 0 replies; 27+ messages in thread
From: Edgar Friendly @ 2012-01-20 14:05 UTC (permalink / raw)
  To: oliver, caml-list

On 01/20/2012 08:58 AM, oliver wrote:
> On Fri, Jan 20, 2012 at 08:29:09AM -0500, Edgar Friendly wrote:
> [...]
>> if a then if b then [a;b] else [a]
>> else if b then [b] else []
> [...]
>
> For me, the original pattern matching code looks much easier to read.
>
I agree - this was not meant to be a suggestion on how to make the 
original code easy to read, but instead to point out that it's as 
efficient as this ugly "optimized" code.  I included it in my benchmark 
as well for only this reason, to verify that the original code was as 
efficient as it.

E.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:29     ` Edgar Friendly
  2012-01-20 13:50       ` Fabrice Le Fessant
  2012-01-20 13:58       ` oliver
@ 2012-01-20 14:12       ` David Allsopp
  2012-01-20 14:23         ` Fabrice Le Fessant
  2012-01-20 14:23         ` Edgar Friendly
  2 siblings, 2 replies; 27+ messages in thread
From: David Allsopp @ 2012-01-20 14:12 UTC (permalink / raw)
  To: Edgar Friendly, caml-list

Edgar Friendly wrote:
> On 01/20/2012 03:37 AM, David Allsopp wrote:
> > Actually, it's possible that with more cases it might be faster - it's
> > eliminating the allocation (at some point) of all the tuples needed
> > for the match case,
> 
> Doesn't the ocaml compiler not allocate the unnecessary tuples?
> https://ocaml.janestreet.com/?q=node/90
> 
> > it potentially eliminates a lot of linear comparisons to find the
> > correct match case (I don't think that the compiler would be able to
> > optimise that to a hash-based or index-based lookup)
> 
> Isn't the compiler's compilation strategy for match cases able to build an
> optimized tree of comparisons in cases like this?  I agree there's no easy
> index or hash strategy for this, but I'd expect it to turn this pattern
> matching into the equivalent of:
> 
> if a then if b then [a;b] else [a]
> else if b then [b] else []

Maybe for this case with two variables, yes - but it can't do that indefinitely: as the number of variables increases, the code size increases exponentially.


David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 14:12       ` David Allsopp
@ 2012-01-20 14:23         ` Fabrice Le Fessant
  2012-01-20 14:23         ` Edgar Friendly
  1 sibling, 0 replies; 27+ messages in thread
From: Fabrice Le Fessant @ 2012-01-20 14:23 UTC (permalink / raw)
  To: David Allsopp; +Cc: Edgar Friendly, caml-list

On Fri, Jan 20, 2012 at 3:12 PM, David Allsopp <dra-news@metastack.com> wrote:
> Maybe for this case with two variables, yes - but it can't do that indefinitely: as the number of variables increases, the code size increases exponentially.

The problem is not the compilation of pattern-matching (number of
tests will still be close to optimal), it is just that the number of
cases to discriminate increases exponentially with the number of
variables.

--Fabrice

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 14:12       ` David Allsopp
  2012-01-20 14:23         ` Fabrice Le Fessant
@ 2012-01-20 14:23         ` Edgar Friendly
  1 sibling, 0 replies; 27+ messages in thread
From: Edgar Friendly @ 2012-01-20 14:23 UTC (permalink / raw)
  To: David Allsopp; +Cc: caml-list

On 01/20/2012 09:12 AM, David Allsopp wrote:
> Maybe for this case with two variables, yes - but it can't do that indefinitely: as the number of variables increases, the code size increases exponentially.

true, the right way to generalize this is to use vuillion's `maybe` 
function that prepends conditionally.  My main point is that the 
original match statement is not bad in efficiency, and does, in fact, 
run 35% faster for the 2-variable case.

E.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:59   ` Edgar Friendly
@ 2012-01-20 14:42     ` oliver
  2012-01-20 15:31     ` Fabrice Le Fessant
  2012-01-20 21:04     ` oliver
  2 siblings, 0 replies; 27+ messages in thread
From: oliver @ 2012-01-20 14:42 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Fri, Jan 20, 2012 at 08:59:31AM -0500, Edgar Friendly wrote:
> On 01/20/2012 04:38 AM, oliver wrote:
> >More concise does not always mean better readable or more performant.
> >You apply the same kind of selection for both values.
> 
> I can't measure readability, but I did throw together a quick
> benchmark to test the different methods.  Please take no offense at
> this - I'm sure that the responses were headed much more towards
> readability than performance,

Thats not offending, the result is fine for me. :-)

I preferred the pattern-match version, because I like
things to be displayed in tables. ;-)

My version (option type and folding on lists) you did not implemented, but
maybe it would have been my work to do that.
But I liked the pattern macthing way.

That it also is the fastest way, is a fine result. :-)

I hope you used more than one call of the function and
used average / stddev on your values to get reliable results...

I don't know your Bench-module.
Where is it from?

Ciao,
   Oliver


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:59   ` Edgar Friendly
  2012-01-20 14:42     ` oliver
@ 2012-01-20 15:31     ` Fabrice Le Fessant
  2012-01-20 21:04     ` oliver
  2 siblings, 0 replies; 27+ messages in thread
From: Fabrice Le Fessant @ 2012-01-20 15:31 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Fri, Jan 20, 2012 at 2:59 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> On 01/20/2012 04:38 AM, oliver wrote:
> let (|>) x f = f x (* no %revapply yet *)
> let lefessant (out, value) = [] |> maybe value v |> maybe out o

I replayed your bench on 3.12.1+dev, where "%revapply" is available,
and it is fortunately the same speed as Jerome Vouillon's one.

--Fabrice

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20  6:38 [Caml-list] is there a more concise way to write this? Martin DeMello
                   ` (2 preceding siblings ...)
  2012-01-20  9:38 ` oliver
@ 2012-01-20 20:40 ` oliver
  2012-01-20 21:07   ` Martin DeMello
  3 siblings, 1 reply; 27+ messages in thread
From: oliver @ 2012-01-20 20:40 UTC (permalink / raw)
  To: Martin DeMello; +Cc: OCaml List

On Thu, Jan 19, 2012 at 10:38:53PM -0800, Martin DeMello wrote:
>       let a = match (out, value) with
>         (true, true)  -> [o; v]
>       | (false, true) -> [v]
>       | (true, false) -> [o]
>       | (false, false) -> []
[...]


Is there a way to get out and value from o and v?


Ciao,
   Oliver

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 13:59   ` Edgar Friendly
  2012-01-20 14:42     ` oliver
  2012-01-20 15:31     ` Fabrice Le Fessant
@ 2012-01-20 21:04     ` oliver
  2012-01-20 21:09       ` oliver
  2 siblings, 1 reply; 27+ messages in thread
From: oliver @ 2012-01-20 21:04 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list


My fold approach version:

let folded (out, value) o v =
  let a = if out   then Some o else None in
  let b = if value then Some v else None in
  List.fold_left ( fun accum elem -> match elem with None -> accum | Some x -> x :: accum ) [] [ b; a ]

or when following the way the other functions are notated
(o and v not as parameters but in the environment) so that
you can paste it into your code:


let folded_env (out, value) =
  let a = if out   then Some o else None in
  let b = if value then Some v else None in
  List.fold_left ( fun accum elem -> match elem with None -> accum | Some x -> x :: accum ) [] [ b; a ]

If
  let ... = ... in  let ... = ...  in ...
is slower than than 
  let ... = ... and let ... = ...  in ...

then use the latter one ;-)


Ciao,
   Oliver

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 20:40 ` oliver
@ 2012-01-20 21:07   ` Martin DeMello
  0 siblings, 0 replies; 27+ messages in thread
From: Martin DeMello @ 2012-01-20 21:07 UTC (permalink / raw)
  To: oliver; +Cc: OCaml List

On Fri, Jan 20, 2012 at 12:40 PM, oliver <oliver@first.in-berlin.de> wrote:
> On Thu, Jan 19, 2012 at 10:38:53PM -0800, Martin DeMello wrote:
>>       let a = match (out, value) with
>>         (true, true)  -> [o; v]
>>       | (false, true) -> [v]
>>       | (true, false) -> [o]
>>       | (false, false) -> []
> [...]
>
>
> Is there a way to get out and value from o and v?

No, out and value are just boolean inputs to the function to control
how the output is built up out of the individual parts.

martin


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] is there a more concise way to write this?
  2012-01-20 21:04     ` oliver
@ 2012-01-20 21:09       ` oliver
  0 siblings, 0 replies; 27+ messages in thread
From: oliver @ 2012-01-20 21:09 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Fri, Jan 20, 2012 at 10:04:30PM +0100, oliver wrote:
> 
> My fold approach version:
> 
> let folded (out, value) o v =
>   let a = if out   then Some o else None in
>   let b = if value then Some v else None in
>   List.fold_left ( fun accum elem -> match elem with None -> accum | Some x -> x :: accum ) [] [ b; a ]
> 
> or when following the way the other functions are notated
> (o and v not as parameters but in the environment) so that
> you can paste it into your code:
> 
> 
> let folded_env (out, value) =
>   let a = if out   then Some o else None in
>   let b = if value then Some v else None in
>   List.fold_left ( fun accum elem -> match elem with None -> accum | Some x -> x :: accum ) [] [ b; a ]
> 
> If
>   let ... = ... in  let ... = ...  in ...
> is slower than than 
>   let ... = ... and let ... = ...  in ...
[...]

meanI t:
If
  let ... = ... in  let ... = ...  in ...
is slower than than 
  let ... = ... and ... = ...  in ...

of course.

(copy & paste-related typo)


Ciao,
   Oliver

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2012-01-20 21:09 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-20  6:38 [Caml-list] is there a more concise way to write this? Martin DeMello
2012-01-20  6:46 ` Valentin ROBERT
2012-01-20  6:58   ` Martin DeMello
2012-01-20  8:37   ` David Allsopp
2012-01-20 13:29     ` Edgar Friendly
2012-01-20 13:50       ` Fabrice Le Fessant
2012-01-20 13:58       ` oliver
2012-01-20 14:05         ` Edgar Friendly
2012-01-20 14:12       ` David Allsopp
2012-01-20 14:23         ` Fabrice Le Fessant
2012-01-20 14:23         ` Edgar Friendly
2012-01-20  8:37   ` Sebastien Ferre
2012-01-20  9:11     ` Jerome Vouillon
2012-01-20  9:34       ` Fabrice Le Fessant
2012-01-20 10:27         ` Arnaud Spiwack
2012-01-20  8:52 ` Lin
2012-01-20  9:08   ` Valentin ROBERT
2012-01-20  9:19     ` Lin
2012-01-20 10:21     ` Martin DeMello
2012-01-20  9:38 ` oliver
2012-01-20 13:59   ` Edgar Friendly
2012-01-20 14:42     ` oliver
2012-01-20 15:31     ` Fabrice Le Fessant
2012-01-20 21:04     ` oliver
2012-01-20 21:09       ` oliver
2012-01-20 20:40 ` oliver
2012-01-20 21:07   ` Martin DeMello

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).