Hi Larry

I have a performance tweak, that gives about an order of magnitude
speedup to paint-cells when running this with a large grid and no or
little (Thread/sleep life-delay) in toggle-thread. That is how I am
running it now - 128 x 192 cells with no delay! It is also noticeably
faster on the more typical size grid.

Type hint is on the graphics param:

(defn paint-cells [#^java.awt.Graphics graphics]
    (time (doseq [[[x,y] state] @cells]
         (doto graphics
            (. setColor (if state Color/RED Color/WHITE))
            (. fillRect (* cell-size x) (* cell-size y) cell-size cell-
size)))))

Example, with type hint:

"Elapsed time: 45.871193 msecs"
"Elapsed time: 39.209662 msecs"
"Elapsed time: 43.899504 msecs"

Without:

"Elapsed time: 529.635331 msecs"
"Elapsed time: 438.145769 msecs"
"Elapsed time: 442.839872 msecs"

I would imagine there may be some other way to get clojure to cache
the reflected handle to Graphics, but I am still a little new to this
so don't have any other ideas on how to eliminate the high amount of
reflection without a type hint.

-Scott
http://fraser.blogs.com/

On Mar 4, 4:17 pm, Larry Sherrill <lps...@gmail.com> wrote:
> I've incorporated everyone's suggestions and thought I would post the
> resulting smaller code. I refactored init-cells away and just pass in
> an init or new function to calc-state to reuse the for loop. I made
> determine-next-state a little more verbose than technically necessary
> to makeconway'srules more obvious to me. The refs "cells" and
> "running" don't feel very functional but I don't know how to get rid
> of them.
>
> (import '(javax.swing JFrame JPanel JButton)
>         '(java.awt BorderLayout Dimension Color)
>         '(java.awt.event ActionListener))
>
> (def cells (ref {}))
>
> (def running (ref false))
>
> (defn determine-initial-state [x y]
>   (= 0 (rand-int 5)))
>
> (defn determine-new-state [x y]
>   (let [neighbor-count
>          (count (for [dx [-1 0 1] dy [-1 0 1]
>                   :when (and (not (= 0 dx dy))
>                              (cells [(+ x dx) (+ y dy)]))]
>                   :alive))]
>     (if (cells [x y])
>         (< 1 neighbor-count 4)
>         (= neighbor-count 3))))
>
> (defn calc-state [cell-state]
>   (dosync
>     (ref-set cells
>       (reduce conj {}
>         (for [x (range 32) y (range 48)]
>           [[x y] (cell-state x y)])))))
>
> (defn paint-cells [graphics]
>      (doseq [[[x, y] state] @cells]
>        (doto graphics
>          (. setColor (if state Color/RED Color/WHITE))
>          (. fillRect (* 10 x) (* 10 y) 10 10))))
>
> (defn toggle-thread [panel button]
>     (if @running
>
>       (do (dosync (ref-set running false))
>           (. button (setText "Start")))
>
>       (do (dosync (ref-set running true))
>           (. button (setText "Stop"))
>           (. (Thread.
>                  #(loop []
>                     (calc-state determine-new-state)
>                     (. panel repaint)
>                     (Thread/sleep 100)
>                     (if @running (recur))))
>                  start))))
>
> (defn main[]
>
>     (calc-state determine-initial-state)
>
>     (let [f (JFrame.)
>           b (JButton. "Start")
>           panel (proxy [JPanel] [] (paint [graphics] (paint-cells
> graphics)))]
>
>         (doto f
>             (. setLayout (BorderLayout.))
>             (. setLocation 100 100)
>             (. setPreferredSize (Dimension. 320 540))
>             (. add b BorderLayout/SOUTH)
>             (. add panel BorderLayout/CENTER)
>             (. setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
>             (. pack)
>             (. setVisible true))
>
>         (. b addActionListener
>            (proxy [ActionListener] []
>                 (actionPerformed [evt] (toggle-thread panel b))))))
>
> (main)
>
> Thanks for everyone. Very good learning experience.
> Larryhttp://lpsherrill.blogspot.com

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