I've noticed a related performance bottleneck when working with
clojure on dalvik. Without type hints methods get looked up using
reflection every time using clojure.lang.Reflector.getMethods. A lot
if time is spend in this method while the results can easily be
cached. This is probably only related to code calling Java (or other
non-clojure) methods.
For my work on dalvik, I patched getMethods:
http://github.com/remvee/clojure/commit/90d31c63b1b2a1fe5ee0ba9ab30915ed039d0fe5
Question to the core contributors: should I open an issue with a patch
for this? Or are there better ways to solve this?
On Sun, Mar 15, 2009 at 3:03 AM, Scott Fraser <
Scott.E...@gmail.com> wrote:
>
> 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
>
> >
>