performance measurements

Each table row shows performance measurements for this Clojure program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
1,0002.852.8762,0961069  1% 0% 1% 100%
4,0006.886.8983,8401069  1% 0% 0% 100%
16,00058.0958.11107,9161069  0% 1% 1% 100%

Read the ↓ make, command line, and program output logs to see how this program was run.

Read mandelbrot benchmark to see what this program should do.


java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Server VM (build 25.0-b70, mixed mode)

Clojure 1.6.0

 mandelbrot Clojure #6 program source code

;;   The Computer Language Benchmarks Game

;; contributed by Andy Fingerhut

;; The function 'dot' is based on suggestions and improvements made by
;; these people posting to the Clojure Google group in April, 2009:
;; dmitri.sotnikov, William D. Lipe, Paul Stadig, michael.messinides
;; David Sletten, John Harrop

;; change by Marko Kocic
;; reduced code size by removing functions already present in Clojure

;; change by Andy Fingerhut
;; Use Java primitive double arrays instead of Clojure sequences in a
;; few inner loops.  This is a parallel version, identical to the
;; sequential version except using pmap in compute-rows.

(ns mandelbrot
  (:import ( BufferedOutputStream)))

(set! *warn-on-reflection* true)

;; Handle slight difference in function name between Clojure 1.2.0 and
;; 1.3.0-alpha* ability to use type hints to infer fast bit
;; operations.
(defmacro my-unchecked-add-int [& args]
  (if (and (== (*clojure-version* :major) 1)
           (== (*clojure-version* :minor) 2))
    `(unchecked-add ~@args)
    `(unchecked-add-int ~@args)))

(defmacro my-unchecked-dec-int [& args]
  (if (and (== (*clojure-version* :major) 1)
           (== (*clojure-version* :minor) 2))
    `(unchecked-dec ~@args)
    `(unchecked-dec-int ~@args)))

(defmacro my-unchecked-divide-int [& args]
  (if (and (== (*clojure-version* :major) 1)
           (== (*clojure-version* :minor) 2))
    `(unchecked-divide ~@args)
    `(unchecked-divide-int ~@args)))

(defmacro my-unchecked-inc-int [& args]
  (if (and (== (*clojure-version* :major) 1)
           (== (*clojure-version* :minor) 2))
    `(unchecked-inc ~@args)
    `(unchecked-inc-int ~@args)))

(def max-iterations 50)
(def limit-square (double 4.0))

(defn dot [r i]
  (let [f2 (double 2.0)
        limit-square (double limit-square)
        iterations-remaining (int max-iterations)
        pr (double r)
        pi (double i)]
    ;; The loop below is similar to the one in the Perl subroutine dot
    ;; in mandelbrot.perl, with these name correspondences:
    ;; pr <-> Cr, pi <-> Ci, zi <-> Zi, zr <-> Zr, zr2 <-> Tr, zi2 <-> Ti
    (loop [zr (double 0.0)
           zi (double 0.0)
           i (int (my-unchecked-inc-int iterations-remaining))]
      (let [zr2 (* zr zr)
            zi2 (* zi zi)]
        (if (and (not (zero? i))
                 (< (+ zr2 zi2) limit-square))
          (recur (+ (- zr2 zi2) pr)
                 (+ (* (* f2 zr) zi) pi)
                 (my-unchecked-dec-int i))
          (zero? i))))))

(defn index-to-val [i scale-fac offset]
  (+ (* i scale-fac) offset))

(defn ubyte [val]
  (if (>= val 128)
    (byte (- val 256))
    (byte val)))

(defn compute-row [#^doubles x-vals y]
  (let [y (double y)
        n (int (alength x-vals))
        num-bytes-out (int (my-unchecked-divide-int (my-unchecked-add-int n 7) 8))
        #^bytes result (byte-array num-bytes-out)
        zero (int 0)
        one (int 1)]
    (loop [i (int zero)
           b (int zero)
           num-filled-bits zero
           result-idx (int zero)]
      (if (== i n)
          (when (not (zero? num-filled-bits))
            (let [last-byte-val
                  (byte (ubyte (bit-shift-left b (- 8 num-filled-bits))))]
            (aset result result-idx last-byte-val)))
        ;; else
        (let [new-bit (int (if (dot (aget x-vals i) y) one zero))
              new-b (int (my-unchecked-add-int (bit-shift-left b one) new-bit))]
          (if (== num-filled-bits 7)
            (let [byte-val (byte (ubyte new-b))]
              (aset result result-idx byte-val)
              (recur (my-unchecked-inc-int i)
                     (my-unchecked-inc-int result-idx)))
            (recur (my-unchecked-inc-int i)
                   (my-unchecked-inc-int num-filled-bits)

(defn compute-rows [size]
  (let [two-over-size (double (/ 2.0 size))
        x-offset (double -1.5)
        y-offset (double -1.0)
        x-vals (double-array size (map #(index-to-val % two-over-size x-offset)
                                       (range size)))
        y-vals (double-array size (map #(index-to-val % two-over-size y-offset)
                                       (range size)))]
    (pmap #(compute-row x-vals (aget y-vals %))
          (range size))))

(defn do-mandelbrot [size]
  (let [rows (compute-rows size)]
    (printf "P4\n")
    (printf "%d %d\n" size size)
    (let [ostream (BufferedOutputStream. System/out)]
      (doseq [r rows]
        (. ostream write r 0 (count r)))
      (. ostream close))

(defn -main [& args]
  (let [size (. Integer valueOf (nth args 0) 10)]
    (do-mandelbrot size)

 make, command-line, and program output logs

Sat, 19 Apr 2014 00:09:57 GMT

mv mandelbrot.clojure-6.clojure mandelbrot.clj
/usr/local/src/jdk1.8.0/bin/java -Dclojure.compile.path=. -cp .:/usr/local/src/clojure/clojure-1.6.0.jar: clojure.lang.Compile mandelbrot
Compiling mandelbrot to .
2.05s to complete and log all make actions

/usr/local/src/jdk1.8.0/bin/java -server -XX:+TieredCompilation -XX:+AggressiveOpts -XX:+UseBiasedLocking -Xmx128m -cp .:/usr/local/src/clojure/clojure-1.6.0.jar: mandelbrot 16000


Revised BSD license

  Home   Conclusions   License   Play