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
Post a Comment