A couple of thoughts: You should be using 1.3.0-beta1 of Clojure 1.3 -- anything with -master-SNAPSHOT is woefully out of date at this point.
No, reduce always returns an Object, and will always box the result of the function you're using in the reduce. Clojure's type inference does not work across HOF application, so compute-step can declare or hint whatever return type you like, but reduce's result will only every be known as an Object (same goes for other results from HOF usage). Your DoubleMersenneTwister ctor is flagged with a reflection warning because swap! returns an Object as well (I assume it's looking for an int or long?). Same principles apply. However, I wouldn't expect (much of) a speedup from those minor tweaks. First, if that reduce with the `compute-step` fn is your hot loop, reduce will box you into oblivion. At least until primitives work across applications of HOFs, you'll need to unroll that by hand. Second, you're destructuring with `[next-put-value next-call-value]`. Destructuring is convenient and usually not a bottleneck, but it often is if you're attempting to avoid boxing overhead: what you have now is boxing the two values you're binding, and then creating a vector to hold them, and then pulling that vector apart to get to the original values. You can just move your conditional out of the let's binding vector, and use it to choose between two recur paths: (if (pos? delta-price) (recur (+ put-value delta-price) call-value) (recur put-value (- call-value delta-price))) Assuming all of the values involved are primitives, the above will ensure that they remain so. - Chas On Jul 23, 2011, at 7:41 AM, bernardH wrote: > Hi, > > I have rewritten some number crunching code from C++ to Clojure. > I was pleasantly surprised to find that the Clojure code is within 10x > of the C++ excecution time (both multicore implementations), but > always eager for more speed, I (reluctantly) moved away from incanter > (only used a couple of thin wrappers over Colt) to Clojure 1.3 > (Clojure 1.3.0-master-SNAPSHOT) for type hinting. > > However, no matter how hard I try, I fail to resolve some > "recur arg for primitive local: put_value is not matching primitive, > had: Object, needed: double" > leading to "Auto-boxing loop arg: put-value" in the most performance > sensitive code :( > > ( complete code on github [*]) the relevant parts are : > > (let [double-normal-rng (Normal. 0. volatility > > (DoubleMersenneTwister. (swap! seed inc)))] > (loop [put-value 0. > call-value 0.] > (if (neg? (swap! n-iters-todo dec)) > [put-value call-value] > (let [delta-price (- strike-price > (reduce compute- > step stock-price > (repeatedly n- > steps > > #(.nextDouble double-normal-rng > > 0. volatility)))) > [next-put-value next-call-value] (if > (pos? delta-price) > [(+ > put-value delta-price) call-value] > [put- > value (- call-value delta-price)])] > (recur next-put-value next-call- > value))))))))) > > And with > (set! *warn-on-reflection* true) > (set! *unchecked-math* true) > I get > Reflection warning, NO_SOURCE_PATH:2535 - call to > cern.jet.random.tdouble.engine.DoubleMersenneTwister ctor can't be > resolved. > NO_SOURCE_FILE:2548 recur arg for primitive local: put_value is not > matching primitive, had: Object, needed: double > NO_SOURCE_FILE:2548 recur arg for primitive local: call_value is not > matching primitive, had: Object, needed: double > Auto-boxing loop arg: put-value > Auto-boxing loop arg: call-value > > When I eval the whole function def. :( > I should note that have type hinted the inner most function, > previously defined in a letfn > (compute-step > ^:static ^double [^double price ^double rnd-number] > (* price (+ 1. > (* rnd-number (Math/sqrt (/ years-to-maturity > n-steps))) > (* risk-free-rate (/ years-to-maturity n- > steps))))) > > What is wrong with the DoubleMersenneTwister ctor ? > Shouldn' t the reduce call preserve the type information from > compute ? strike-price is type-hinted to double so shouldn't the > *unchecked-math* preserve this type info all the way to next-put-value > and next-call-value ? > > Any help (even only a hint ;) on where to look for) *greatly* > appreciated ! > > Best Regards, > > Bernard > > [*] > https://github.com/scientific-coder/Black-Scholes/blob/master/src/black-scholes/src/montecarlo.clj#L57 > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en