clojure - Improve performance of a ClojureScript program -


i have clojurescript program performs math calculations on collections. developed in idiomatic, host-independent clojure, it's easy benchmark it. surprise (and contrary answers suggest which faster, clojure or clojurescript (and why)?), same code in clojurescript runs 5-10 times slower clojure equivalent.

here did. opened lein repl , browser repl @ http://clojurescript.net/. tried these snippets in both repls.

 (time (dotimes [x 1000000] (+ 2 8)))   (let [coll (list 1 2 3)] (time (dotimes [x 1000000] (first coll)))) 

then opened javascript console @ browser repl , wrote minimalist benchmark function,

 function benchmark(count, fun) {    var t0 = new date();    (i = 0; < count; i++) {      fun();    }    var t1 = new date();    return t1.gettime() - t0.gettime();  } 

back browser repl:

 (defn multiply [] (* 42 1.2)) 

then try both native javascript multiplication, , clojurescript variant in javascript console,

 benchmark(1000000, cljs.user.multiply);   benchmark(1000000, function(){ 42 * 1.2 }); 

what found

  • native javascript math comparable math in clojure
  • clojurescript 5-10 times slower either of them

now question is, how can improve performance of clojurescript program?

there approaches i've considered far

  • fall using mutable javascript arrays , objects behind scenes. (is possible @ all?)
  • fall using native javascript math operators. (is possible @ all?)
  • use javascript arrays explicitly (aget js/v 0)
  • use less ambitious implementation of clojure-for-javascript, https://github.com/chlorinejs/chlorine or https://github.com/gozala/wisp generate more idiomatic javascript, don't support namespaces 'm using lot.

javascript has explicit return, so

function () { 42 * 1.2 } 

does nothing; you'll want benchmark

function () { return 42 * 1.2 } 

instead. happens clojurescript version compiles to, there won't difference (in clojurescript, basic arithmetic functions in non-higher-order usage inlined regular operator-based javascript expressions).

now, clojure faster clojurescript @ point. part of reason clojure still more tuned clojurescript, although clojurescript improving @ pretty great pace in department. part clojure has more mature jit take advantage of (the modern js engines, v8 in particular, pretty great, not quite hotspot-grade yet).

the magnitude of difference tricky measure, though; fact jits involved means loop body free of side effects, such 1 in question, optimized away, possibly on first run through (through use of on-stack replacement, used hotspot , i think v8 -- i'd have check sure though). so, better benchmark like

(def arr (long-array 1))  ;;; benchmark (dotimes [_ 1000000]   (aset (longs arr) 0 (inc (aget (longs arr) 0)))) 

(longs call avoid reflection in clojure; use ^longs hint).

finally, case, in both clojure , clojurescript, kinds of particularly performance-sensitive code it's best use native arrays , such. happily, there's no problem doing so: on clojurescript side, you've got array, js-obj, aget, aset, make-array, can use :mutable metadata on fields in deftype able set! them in method bodies etc.


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -