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