62 comments

[ 2.8 ms ] story [ 128 ms ] thread
Very impressive, I am glad I started studying clojure earlier this summer, I feel it will be a powerful tool in years to come. Currently working on a Cljs life simulation engine (flora, fauna, think Rich Hickeys Ant Colony demo)
(comment deleted)
I feel like a broken record for saying this but ... most production JS is shipped minified just like the code for this post. The entire code base is 25K gzipped smaller than ES6 generators + jQuery + Underscore + Immutable Collection Library + Promises implementation which is what ClojureScript + core.async delivers!
Suggested not to view on a mobile device - works just fine on an iPhone 5, actually.
Same, on my iPhone 4S...
Works fine on my HTC One S
Works fine on Android stock browser (Galaxy Nexus)
Works on BB, Q10.
(comment deleted)
It even runs along fine on my old ZTE Blade (the DOM updates are certainly not in a hurry, but the text field remains responsive).
Even more fun and guaranteed to crash everything except for desktop Chrome & WebKit Nightly is the follow up http://swannodette.github.io/2013/08/02/100000-processes/ - here we create 100,000 go blocks (akin to 100,000 goroutines in golang) and run them all at the same time.
That's pretty cool. You don't need WebKit nightly, it runs fine for me on Safari 6.0.5.
Yeah this also works quite well in IE10.
it works. but fine may be the wrong word if you compare it to Chrome... (slower, less responsive when e.g. scrolling)
Works on desktop chrome on stable channel.
Works fine on Opera 15.
(comment deleted)
A little chunky but did ok on mobile safari, iOS 6 on iPhone 4s
Barely laggy on a throttle core2duo 800Mhz running Firefox Nightly. Try harder
It works flawlessly on iOS 7 on iPhone 5 as does the original.
Seems to work fine on Chrome for Android too.
(comment deleted)
I tried on firefox 22, it took 4:54 mn to complete , each color was around 4 to 8 numbers. I then tried on IE10 to have some fun : I took 7 sec to complete, each color was between 1 and 3 lines ...
Just to explain core.async uses the fastest dispatching mechanism available, Firefox doesn't provide anything sensible like MessageChannel so we just resort to setTimeout. setTimeout in all major browsers has a 5ms delay between nested calls - thus all the discussion about setImmediate the past 2 years or so.

I am surprised about IE 10 since we do use setImmediate if available, but I haven't done much testing there - will need to look into it.

Thanks for the explanation. On your machine what time does it take to color all the numbers on : IE10, Firefox and Chrome ?
FF probably takes about the same time - Chrome takes only a 5-6 seconds. I don't have IE 10 handy.
FF takes longer just because the script is pretty broken, imo: it only processes 4-5 chars per 16ms frame, and reflowing/painting each frame tick here is the expensive thing in all browsers. As a result, the behavior of the script in wall-clock time is O(N^2/K) where N is the number of chars and K is the number it processes in a single tick. Furthermore, its CPU consumption is pretty much constant no matter what K is for a wide range of K.
Why can't you use postMessage? I use it for low-latency callbacks ala setImmediate and it works fine.
Can you use window.postMessage() on Firefox? Barnes & Noble's (?!) NobleJS library has a setImmediate() polyfill, which uses postMessage() on Firefox:

https://github.com/NobleJS/setImmediate/blob/master/setImmed...

We could use postMessage but it's rather frustrating since that's a global post and we have detect our own messages on the other side. So until Firefox supports MessageChannel we're unlikely to go that route.
What do you use on Chrome?

What I see is that the page is using self-throttling to a ridiculous extent in Firefox, but not Chrome, with way too few letters changed between paints. Are you doing a single letter from each async callback or something?

(comment deleted)
What language is that it's showing at the bottom?
Clojure[1]. I watched two one-hour videos trying to learn the language and my brain exploded.

http://en.wikipedia.org/wiki/Clojure

That sounds horribly painful. I hope you are doing ok.
Luckily joeblau uploaded his consciousness into his Roomba nanoseconds before his brain exploded, that's how he can still post to HN. So at least there's that.
Where is the template and code that handles DOM manipulation, classes, etc?

How does it get so fast even without setImmediate? Does it use the postMessage or MutationObserver tricks?

It's always great to see ClojureScript pushing forward on things like this. I've recently started focusing on Clojure and Clojure script for personal projects and I'm really enjoying functional programming.
Isn't this 100x100 = 10,000 updates?
Oops you are correct, brain stuck on other benchmarks I've been working on - the posts now actually involve 100,000 updates and/or processes. Thanks
I wonder if the fact it's immensely slow on FF 22 vs Chrome 28 is worth a Bugzilla ticket
The page is, as far as I can tell, running different code in Firefox and Chrome...
The bug for MessageChannel is https://bugzilla.mozilla.org/show_bug.cgi?id=677638 (I just poked it, we should fix it).

The test needs to be changed to try postMessage on Firefox and any other browser version lacking MessageChannel, or else it should just fail with an alert -- "waiting for Firefox to implement MessageChannel" -- because what it's doing on Firefox is an irrelevant timekiller, as bz showed a few comments above at https://news.ycombinator.com/item?id=6154170.

On swannodette's previous blogpost, he wrote in Reactive style:

    (defn ex0-key-events [prevent-default?]
      (->> (events js/window "keydown" prevent-default?)
           (map key-event->keycode)
           (filter KEYS)
           (map key->keyword)))
Where did the `events` function (line 2) come from? Does it create a lazy dechunked seq which takes events from a buffered channel? Is it built atop RxJS?

(Sorry, I haven't yet used ClojureScript, only Clojure. Googling didn't help.)

My JavaScript isn't great, so I'm ignoring prevent-default?, but you can probably do something like this:

  (defn events [object type]
    (let [out (chan)]
      (.addEventListener object type (fn [e] (put! out e)))
      out))
(comment deleted)
What's the point of using clojure to js ?
The argument for Clojurescript is about the same as for Clojure on the JVM. To get a (subjectively) more expressive language but have it run on an already popular platform and take advantage from that.
Nightly - 25.0a1 Firefox - 22 Chrome - 28.0.1500.95

way way way faster on chrome than on either nightly/firefox

Yep, because it's running different code in different browsers. See swannodette's comments above.
This really should say right up front that you should not compare it across browsers because it's serving significantly different code to the different browsers.