On Wednesday, July 8, 2015 at 4:37:13 PM UTC+3, Aleksey Kladov wrote: > Hello! > > I'm trying to use core.async to wrap nodejs callback based API into > channels. To measure core.async overhead I have created a simple benchmark, > located here: https://github.com/matklad/asyncbench. > > The problem is, I can't really explain benchmark's results. > > The benchmark is simple: sum numbers from 1 to N, invoking each summation > step as a callback after a certain delay. JavaScript and ClojureScript > callback-based versions are straight forward (although in cljs version local > mutabels via singleton arrays are used). For core.async version, callback > just writes result to async/chan, which is read from in a go-loop block. > > > If delay is done via setTimeout or via nodejs nanotimer, I get similar results > for JavaScript, ClojureScript callbacks and for ColureScript core.async, like > this (N = 2000 numbers, 100 microsecond delay): > > JavaScript x 4.79 ops/sec > ClojureScript callbacks x 4.71 ops/sec > ClojureScript async x 4.36 ops/sec > > > If instead the delay is just process.nextTick, core.async lags behind: > > JavaScript x 443 ops/sec > ClojureScript callbacks x 316 ops/sec > ClojureScript async x 37.79 ops/sec > > > Is this performance drop due to core.async overhead? Or is it some peculiarity > of how core.async uses node event loop? My initial guess was that core.async > schedules itself with some delay, however it does use node's > process.nextTick/setImmediate. > > What's even more surprising is that when the delay is really tiny (say, 10 > nanoseconds), core.async becomes faster then with a nextTick delay, like this > (N = 1000): > > nextTick: > ClojureScript callbacks x 418 ops/sec > ClojureScript async x 67.47 ops/sec > > 10ns delay: > ClojureScript callbacks x 111 ops/sec > ClojureScript async x 141 ops/sec > > > So, how this figures can be explained?
Well, I guess I figured out why async with a tiny delay performs faster on the benchmark than async without any delay. goog.async.nextTick under node is an alias to setImmediate. However, node also has process.nextTick, which is "faster", but may case IO tasks to starve. And with tiny delays, node nanotimers schedules tasks with process.nextTick. If I change async's queue_dispatcher to use process.nextTick, I get numbers similar to x 141 ops/sec. -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
