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