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
-~----------~----~----~----~------~----~------~--~---

Reply via email to