On Wed, Oct 26, 2011 at 1:31 AM, Cedric Cellier <[email protected]>wrote:

> While comparing async and lwt you forget to mention performances. Didn't
> you run any benchmark with some result to share ? Or are Async performances
> irrelevant to your use cases so you never benchmarked ?


Perhaps surprisingly, while we've benchmarked and tuned the performance of
Async, but we've never done the same for Lwt.

This has to do with history as much as anything else.  We wrote the first
version of Async years ago, when Lwt was much less mature.  We looked at Lwt
at the time and decided that there were several design choices that made it
unsuitable for our purposes, so we wrote Async.  We've looked back at Lwt
for inspiration over the years, but we've never again had the question in
front of us as to whether to use Lwt or Async, so doing the benchmarking has
never been high on our list.

We do have some guesses about how performance differs.  For example, Lwt's
bind is faster than Async's bind because of different interleaving policies:
Lwt can run the right-hand side of a bind immediately, whereas in Async,
it's always scheduled to run later, so that's more work that Async has to do
in.  That said, we prefer the semantics of Async's bind, even though it has
a performance cost.  (You can easily implement Lwt-style bind.)

Another thing to note for any intrepid benchmarkers is that the released
version of Async is missing a useful feature that is already available in
our development trunk, which is tail-recursive bind.  In the released
version, the following loop:

let rec loop () =
   after (sec 30.)
   >>= fun () ->
   printf ".%!";
   loop ()

will allocate an unbounded amount of space, creating one deferred value
every 30 seconds.  In our development trunk bind is tail-recursive, but that
hasn't gotten to the public release yet.

You can do the same loop efficiently in Async using the upon operator:

let rec loop () =
   after (sec 30.)
   >>> fun () ->
   printf ".%!";
   loop ()

This is actually more efficient than using the tail-recursive version of
bind, since it allocates one less deferred value every time through the
loop.

y

-- 
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

Reply via email to