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 <[email protected]> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---