On Apr 2, 2009, at 2:05 AM, MikeM wrote:
> > Starting with your version, I got about a 2x improvement with the > following: > > (defn check-bounds [x y] > (let [f2 (float 2.0) > f4 (float 4.0)] > (loop [px (float x) > py (float y) > zx (float 0.0) > zy (float 0.0) > zx2 (float 0.0) > zy2 (float 0.0) > value (float 0)] > (if (and (< value (*max-steps*)) (< (+ zx2 zy2) f4)) > (let [new-zy (float (+ (* (* f2 zx) zy) py)) > new-zx (float (+ (- zx2 zy2) px)) > new-zx2 (float (* new-zx new-zx)) > new-zy2 (float (* new-zy new-zy))] > (recur px py new-zx new-zy new-zx2 new-zy2 (inc > value))) > (if (== value (*max-steps*)) 0 value))))) > > f2 and f4 didn't do much, most improvement seems to come from (* (* f2 > zx) zy) in place of (* f2 zx zy). Using the arity 2 multiply results > in the multiply being inlined. Building on your and Paul's improvements I simply wrapped (almost) everything in a 'let' rather than using 'def' or Paul's cool macro idea. I also pulled out a couple of divisions from draw-line. This takes about 38% of the time of Paul's version: (let [width (float 640) height (float 640) max-steps (float 32) color-scale (float (quot 255 max-steps)) height-factor (/ 2.5 height) width-factor (/ 2.5 width)] (defn on-thread [#^Runnable f] (doto (new Thread f) (.start))) (defn check-bounds [x y] (let [f2 (float 2.0) f4 (float 4.0)] (loop [px (float x) py (float y) zx (float 0.0) zy (float 0.0) zx2 (float 0.0) zy2 (float 0.0) value (float 0)] (if (and (< value max-steps) (< (+ zx2 zy2) f4)) (let [new-zy (float (+ (* (* f2 zx) zy) py)) new-zx (float (+ (- zx2 zy2) px)) new-zx2 (float (* new-zx new-zx)) new-zy2 (float (* new-zy new-zy))] (recur px py new-zx new-zy new-zx2 new-zy2 (inc value))) (if (== value max-steps) 0 value))))) (defn draw-line [#^Graphics g y] (let [dy (- 1.25 (* y height-factor))] (doseq [x (range 0 width)] (let [dx (- (* x width-factor) 2.0)] (let [value (check-bounds dx dy)] (if (> value 0) (doto g (. setColor (Color. (* value color-scale))) (. drawRect x y 0 0)))))))) (defn draw-lines ([buffer g] (draw-lines buffer g height)) ([#^BufferStrategy buffer g y] (doseq [y (range 0 y)] (draw-line g y) ;(on-thread (draw-line g y)) (. buffer show)))) (defn draw [#^Canvas canvas] (let [buffer (. canvas getBufferStrategy) g (. buffer getDrawGraphics)] (draw-lines buffer g))) (defn main [] (let [panel (JPanel.) canvas (Canvas.) frame (JFrame. "Mandelbrot")] (doto panel (.setPreferredSize (Dimension. width height)) (.setLayout nil) (.add canvas)) (doto frame (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) (.setBounds 0,0,width height) (.setResizable false) (.add panel) (.setVisible true)) (doto canvas (.setBounds 0,0,width height) (.setBackground (Color/BLACK)) (.createBufferStrategy 2) (.requestFocus)) (draw canvas)))) Aloha, David Sletten --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---