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