caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] react performance tips?
       [not found] <20141112110013.E26627FAE2@sympa.inria.fr>
@ 2014-11-13 17:13 ` Nils Becker
  0 siblings, 0 replies; only message in thread
From: Nils Becker @ 2014-11-13 17:13 UTC (permalink / raw)
  To: caml-list

hi,

tl;dr: i'm looking for feedback on how to optimize performance in a
react-based system. minimal self contained code (160 lines) is here:
https://gist.github.com/nilsbecker/2ec8d0a136e2fcc20184#file-react_minibenchmark-ml


i've been experimenting on and off with React for an event-driven
simulation. at the moment i cannot seem to make it similarly fast as a
conventional imperative scheme using mutable state.

the gist contains a boiled-down simplified version of the tight loop
of the simulation. in each update step, a randomly chosen one out of a
pool of updaters fires. the only effect is to increment a global
counter. (this is trivial but in the actual code the update is still
very cheap to compute)


i implemented this in different ways:

1. "pure". the updaters are (int -> int) events. they are combined
into a single event using E.select. the global counter is a signal
derived from that using S.accum.

2. "side-effect". the global count is an int signal. the updaters are
(unit -> unit) events which as a side effect increment the global
count. they don't need to be combined since the side effects happen
also without.

3. "mutable". react is not used. the updaters are (unit -> unit)
functions which mutate a global int ref.


i like version 1 best since it makes the dependencies explicit.
version 2 is almost like imperative programming. the benefit is that
one can still use react to conventiently add downstream signals, e.g.
to write out the simulation state at regular intervals etc. version 3
does not have this advantage.

when profiling, i found:

- 1. is a bit slower than 2. for small numbers of updaters but really
  slow for many. it seems that E.select is the culprit, causing linear
  scaling

- 2. has runtime independent of the number of updaters

- most of the time is spent in gc and creating new weak arrays.

- 3. is at least 10 times faster than 1. or 2.

- when trivial intermediate events are built into 1. this slows down
  execution. there is a non-negligible cost for traversal of
  dependency chains.


so my questions are:

am i using react in the proper way?

am i doing something stupid that slows it down? what would be a better
setup?

is there a way to combine events that does not suffer from O(n)
performance of a list fold as E.select does?

or is this just the fastest a react-based scheme can run, ie. 10x
slower than imperative updates?

i'm still new. any comments on the code in general are welcome of
course.

thanks a lot for any hints.



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-11-13 17:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20141112110013.E26627FAE2@sympa.inria.fr>
2014-11-13 17:13 ` [Caml-list] react performance tips? Nils Becker

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