From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 300187FAED for ; Thu, 13 Nov 2014 18:14:20 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of nils.becker@bioquant.uni-heidelberg.de) identity=pra; client-ip=129.206.210.211; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nils.becker@bioquant.uni-heidelberg.de"; x-sender="nils.becker@bioquant.uni-heidelberg.de"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of nils.becker@bioquant.uni-heidelberg.de) identity=mailfrom; client-ip=129.206.210.211; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nils.becker@bioquant.uni-heidelberg.de"; x-sender="nils.becker@bioquant.uni-heidelberg.de"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@relay2.uni-heidelberg.de) identity=helo; client-ip=129.206.210.211; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nils.becker@bioquant.uni-heidelberg.de"; x-sender="postmaster@relay2.uni-heidelberg.de"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApwBAKXmZFSBztLTnGdsb2JhbABbg2LNTodNAoEfFgEBAQEBEQEBAQEBCAsJCRQuhAMBBSdiLCUPAkYTCAEBiD0N0HoBCxwEiniGIxaENQWQFoMyg0WIWIYKOoc5izODNwEBAQ X-IPAS-Result: ApwBAKXmZFSBztLTnGdsb2JhbABbg2LNTodNAoEfFgEBAQEBEQEBAQEBCAsJCRQuhAMBBSdiLCUPAkYTCAEBiD0N0HoBCxwEiniGIxaENQWQFoMyg0WIWIYKOoc5izODNwEBAQ X-IronPort-AV: E=Sophos;i="5.07,378,1413237600"; d="scan'208";a="106673276" Received: from relay2.uni-heidelberg.de ([129.206.210.211]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 13 Nov 2014 18:14:03 +0100 Received: from ix.urz.uni-heidelberg.de (cyrus-portal.urz.uni-heidelberg.de [129.206.100.176]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id sADHDwXs012298 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 13 Nov 2014 18:13:59 +0100 Received: from extmail.urz.uni-heidelberg.de (extmail.urz.uni-heidelberg.de [129.206.100.140]) by ix.urz.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id sADHDw1B011154 for ; Thu, 13 Nov 2014 18:13:58 +0100 Received: from bqdyn245_008.bioquant.uni-heidelberg.de (bqdyn245_008.bioquant.uni-heidelberg.de [129.206.245.24]) (authenticated bits=0) by extmail.urz.uni-heidelberg.de (8.13.4/8.13.1) with ESMTP id sADHDved014173 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Thu, 13 Nov 2014 18:13:58 +0100 Message-ID: <5464E6BC.60604@bioquant.uni-heidelberg.de> Date: Thu, 13 Nov 2014 18:13:32 +0100 From: Nils Becker User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: caml-list@inria.fr References: <20141112110013.E26627FAE2@sympa.inria.fr> In-Reply-To: <20141112110013.E26627FAE2@sympa.inria.fr> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Validation-by: nils.becker@bioquant.uni-heidelberg.de Subject: [Caml-list] react performance tips? 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.