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.

Reply via email to