Oops, sorry, I thought my post was stuck in the moderation queue and
have only just noticed the replies while browsing through the list
history! Thanks to everyone who replied.

Your version looks to be about six times faster than mine was. Thanks
ever so much!
In fact I wouldn't have noticed the difference between it and the
scala version by eye.

Having got interested I'll try to do proper timings. Would anyone be
interested in the results?

Cheers, John.

On Mar 2, 6:56 pm, Stuart Halloway <stuart.hallo...@gmail.com> wrote:
> Hi John,
>
> You can get some speedup by using unboxed math in draw-tree (see  
> below).  What kind of speed difference are you seeing?
>
> Stu
>
> (import '(javax.swing JFrame JPanel )
>         '(java.awt Color Graphics Graphics2D))
>
> (defn draw-tree [ #^Graphics g2d angle x y length branch-angle depth]
>    (when (> depth 0)
>      (let [angle (double angle)
>            x (double x)
>            y (double y)
>            length (double length)
>            branch-angle (double branch-angle)
>            depth (double depth)
>            new-x (- x (* length (Math/sin (Math/toRadians angle))))
>            new-y (- y (* length (Math/cos (Math/toRadians angle))))
>            new-length (fn [] (* length (+ 0.75 (rand 0.1))))
>            new-angle  (fn [op] (op angle (* branch-angle (+ 0.75  
> (rand)))))]
>        (. g2d drawLine x y new-x new-y)
>        (draw-tree g2d (new-angle +) new-x new-y (new-length) branch-
> angle (- depth 1))
>        (draw-tree g2d (new-angle -) new-x new-y (new-length) branch-
> angle (- depth 1)))))
>
> (defn render [ #^Graphics g w h]
>   (doto g
>     (.setColor (Color/BLACK))
>     (.fillRect 0 0 w h)
>     (.setColor (Color/GREEN)))
>   (let [init-length ( / (min w h) 5),
>         branch-angle (* 10 (/ w h)),
>         max-depth 12]
>     (draw-tree  g 0.0 (/ w 2) h init-length branch-angle max-depth)))
>
> (defn create-panel []
>     "Create a panel with a customised render"
>
>   (proxy [JPanel] []
>     (paintComponent [g]
>                     (proxy-super paintComponent g)
>                     (time (render g (. this getWidth) (. this  
> getHeight))))))
>
> (defn run []
>   (let [frame (JFrame. "Clojure Fractal Tree")
>         panel (create-panel)]
>     (doto frame
>       (.add panel)
>       (.setSize 640 400)
>       (.setVisible true))))
>
> (run)
>
> > Hi, the other day I was at a conference in London and learned Scala.
>
> > As my first program I translated a favourite fractal tree program
> > (which I stole from:http://marblemice.com/2009/04/26/clojure-fractal-tree/)
> > .
> > The programs are almost exactly the same in the two languages.
>
> > The Scala version seems quite a lot faster than the Clojure one. I
> > added type hints for the Graphics objects, but there's also a
> > reflection warning from the JPanel proxy, which I think is
> > unimportant, but which I can't see how to get rid of.
>
> > Is the reason the Clojure version is slow that recursive calls to  
> > draw-
> > tree are boxing and unboxing primitive types? If so is there anything
> > that can be done? Did I just pick a particularly bad example program?
>
> > Or am I just missing something silly? Is there an easy way to examine
> > the byte-code?
> > Is it human-readable? Can it be done from a REPL like disassemble in
> > Lisp?
>
> > ------------------------------------------- clojure version
>
> > (import '(javax.swing JFrame JPanel )
> >        '(java.awt Color Graphics Graphics2D))
>
> > (defn draw-tree [ #^Graphics g2d angle x y length branch-angle depth]
> >  (if (> depth 0)
> >    (let [new-x (- x (* length (Math/sin (Math/toRadians angle))))
> >          new-y (- y (* length (Math/cos (Math/toRadians angle))))
> >          new-length (fn [] (* length (+ 0.75 (rand 0.1))))
> >          new-angle  (fn [op] (op angle (* branch-angle (+ 0.75
> > (rand)))))]
> >      (. g2d drawLine x y new-x new-y)
> >      (draw-tree g2d (new-angle +) new-x new-y (new-length) branch-
> > angle (- depth 1))
> >      (draw-tree g2d (new-angle -) new-x new-y (new-length) branch-
> > angle (- depth 1)))))
>
> > (defn render [ #^Graphics g w h ]
> >  (doto g
> >    (.setColor (Color/BLACK))
> >    (.fillRect 0 0 w h)
> >    (.setColor (Color/GREEN)))
> >  (let [init-length ( / (min w h) 5),
> >        branch-angle (* 10 (/ w h)),
> >        max-depth 12]
> >    (draw-tree  g 0.0 (/ w 2) h init-length branch-angle max-depth)))
>
> > (defn create-panel []
> >    "Create a panel with a customised render"
>
> >  (proxy [JPanel] []
> >    (paintComponent [g]
> >                    (proxy-super paintComponent g)
> >                    (render g (. this getWidth) (. this getHeight)))))
>
> > (defn run []
> >  (let [frame (JFrame. "Clojure Fractal Tree")
> >        panel (create-panel)]
> >    (doto frame
> >      (.add panel)
> >      (.setSize 640 400)
> >      (.setVisible true))))
>
> > (run)
>
> > ----------------------------------------------- scala version
>
> > import scala.swing._
> > import java.awt._
> > import javax.swing._
>
> > object ScalaFractalTree {
> >       def main(args: Array[String]){
> >                      val frame=new JFrame("Scala Fractal Tree")
> >                      val panel=new MyPanel()
> >                      frame add panel
> >                      frame setSize (640, 400)
> >                      frame setVisible true
>
> >                }
>
> >       }
>
> > class MyPanel extends JPanel{
> >  override def paintComponent(g:Graphics):Unit = {
> >    super.paintComponent(g)
> >    render(g, getWidth(), this.getHeight())
>
> >  }
> >  def render(g:Graphics, w:Int, h:Int){
> >      g.setColor (Color.BLACK)
> >      g.fillRect( 0, 0, w, h)
> >      g.setColor (Color.GREEN)
> >      val initlength=if (w<h) w/5 else h/5
> >      val branchangle=10*w/h
> >      val maxdepth=12
> >      drawtree( g, 0.0, w/2.0, h ,initlength, branchangle, maxdepth)
> >      }
>
> >  def drawtree(g:Graphics, angle:Double, x:Double, y:Double,
> > length:Double,
> >                             branchangle:Double, depth:Double){
> >     if (depth>0){
> >        val newx= x-length*(Math.sin(Math.toRadians( angle)))
> >        val newy= y-length*(Math.cos(Math.toRadians( angle)))
> >        val newlength1 = length*(0.75+0.1*Math.random)
> >        val newlength2 = length*(0.75+0.1*Math.random)
> >        val newangle1  = angle+branchangle*(0.75+Math.random)
> >        val newangle2  = angle-branchangle*(0.75+Math.random)
> >        g.drawLine(x.toInt, y.toInt, newx.toInt, newy.toInt)
> >        drawtree(g, newangle1, newx, newy, newlength1, branchangle,
> > depth-1)
> >        drawtree(g, newangle2, newx, newy, newlength2, branchangle,
> > depth-1)
> >        }
> >  }
> > }
>
> > --
> > 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
> > Note that posts from new members are moderated - please be patient  
> > with your first post.
> > 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

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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