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.fra...@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 > > > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---