I've been playing around with rendering a mandelbrot set, and using pure java it renders about 2 seconds on my machine, however it runs about 10 times as slow in clojure, I was curious if I'm doing anything obviously wrong, or if it's just life :) I do run it with the -server flag, which does improve it a bit. I've got the java and clojure source below:
import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferStrategy; import java.awt.image.ImageObserver; import javax.swing.JFrame; import javax.swing.JPanel; public class Mandelbrot extends Canvas implements ImageObserver { public static final int WIDTH = 640; public static final int HEIGHT = 640; private static int BAILOUT = 4; private static int MAX_ITERATIONS = 32; public BufferStrategy strategy; public Mandelbrot () { setBounds(0,0,WIDTH,HEIGHT); setBackground(Color.BLACK); JPanel panel = new JPanel(); panel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); panel.setLayout(null); panel.add(this); JFrame frame = new JFrame("Mandelbrot"); frame.add(panel); frame.setBounds(0,0,WIDTH, HEIGHT); frame.setResizable(false); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //create a double buffer createBufferStrategy(2); strategy = getBufferStrategy(); requestFocus(); } private int checkBounds(float x, float y) { float cr = x; float ci = y; float zi = 0.0f; float zr = 0.0f; int i = 0; while (true) { i++; float temp = zr * zi; float zr2 = zr * zr; float zi2 = zi * zi; zr = zr2 - zi2 + cr; zi = temp + temp + ci; if (zi2 + zr2 > BAILOUT) return i; if (i > MAX_ITERATIONS) return 0; } } private void draw() { float x = -2.1f, y = -1.5f, z = 3.0f; int i, j; Graphics g = strategy.getDrawGraphics(); g.clearRect(0, 0, getWidth(), getHeight()); for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { int value = checkBounds((x + z*(i/(float)WIDTH)), (y + z*(j/(float) HEIGHT))); if (value > 0) { g.setColor(new Color(value*255/MAX_ITERATIONS)); g.drawRect(i, j, 0, 0); } } strategy.show(); } strategy.show(); } public static void main(String args[]) { Mandelbrot m = new Mandelbrot(); long startTime = System.currentTimeMillis(); m.draw(); System.out.println((System.currentTimeMillis() - startTime)/1000); } } Clojure: (ns main (:import (java.awt Color Container Graphics Canvas Dimension) (javax.swing JPanel JFrame) (java.awt.image BufferedImage BufferStrategy))) (def *width* 640) (def *height* 640) (def *max-steps* 32) (defn on-thread [f] (doto (new Thread f) (.start))) (defn check-bounds [x y] (loop [px x py y zx 0.0 zy 0.0 zx2 0.0 zy2 0.0 value 0] (if (and (< value *max-steps*) (< (+ zx2 zy2) 4.0)) (let [new-zy (+ (* 2.0 zx zy) py) new-zx (+ (- zx2 zy2) px) new-zx2 (* new-zx new-zx) new-zy2 (* new-zy new-zy)] (recur px py new-zx new-zy new-zx2 new-zy2 (inc value))) (if (== value *max-steps*) 0 value)))) (defn draw-line [g y] (let [dy (- 1.25 (* 2.5 (/ y *height*)))] (doseq [x (range 0 *width*)] (let [dx (- (* 2.5 (/ x *width*)) 2.0)] (let [value (check-bounds dx dy)] (if (> value 0) (doto g (. setColor (Color. (* value (/ 255 *max- steps*)))) (. drawRect x y 0 0)))))))) (defn draw-lines ([buffer g] (draw-lines buffer g *height*)) ([buffer g y] (doseq [y (range 0 y)] (draw-line g y) ;(on-thread (draw-line g y)) (. buffer show)))) (defn draw [canvas] (let [buffer (. canvas getBufferStrategy) g (. buffer getDrawGraphics)] (draw-lines buffer g))) (defn main [] (let [panel (JPanel.) canvas (Canvas.) frame (JFrame. "Mandelbrot")] (doto panel (.setPreferredSize (Dimension. *width* *height*)) (.setLayout nil) (.add canvas)) (doto frame (.setDefaultCloseOperation JFrame/ EXIT_ON_CLOSE) (.setBounds 0,0,*width* *height*) (.setResizable false) (.add panel) (.setVisible true)) (doto canvas (.setBounds 0,0,*width* *height*) (.setBackground (Color/BLACK)) (.createBufferStrategy 2) (.requestFocus)) (draw canvas))) (time (main)) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---