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

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.

 notes

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 #2 program source code

;;   The Computer Language Benchmarks Game
;;   http://shootout.alioth.debian.org/

;; 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

(ns mandelbrot
  (:gen-class)
  (:import (java.io BufferedOutputStream)))


(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 (inc 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)
                 (unchecked-dec 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
  [x-vals y]
    (loop [b (int 0)
           num-filled-bits (int 0)
           result (transient [])
           x-vals x-vals]
      (if-let [s (seq x-vals)]
        ;; then
        (let [new-bit (int (if (dot (first s) y) 1 0))
              new-b (int (+ (bit-shift-left b 1) new-bit))]
          (if (== num-filled-bits 7)
            (recur (int 0)
                   (int 0)
                   (conj! result (ubyte new-b))
                   (rest s))
            (recur new-b
                   (int (inc num-filled-bits))
                   result
                   (rest s))))
        ;; else
        (if (zero? num-filled-bits)
          (persistent! result)
          (persistent! (conj! result
                              (ubyte (bit-shift-left b (- 8 num-filled-bits)))))
          ))))


(defn my-lazy-map
  [f coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (cons (f (first s)) (my-lazy-map f (rest s))))))


(defn modified-pmap
;   "Like pmap from Clojure 1.1, but with only as much parallelism as
;   there are available processors.  Uses my-lazy-map instead of map
;   from core.clj, since that version of map can use unwanted additional
;   parallelism for chunked collections, like ranges."
  ([num-threads f coll]
     (if (== num-threads 1)
       (map f coll)
       (let [n (if (>= num-threads 2) (dec num-threads) 1)
             rets (my-lazy-map #(future (f %)) coll)
             step (fn step [[x & xs :as vs] fs]
                    (lazy-seq
                      (if-let [s (seq fs)]
                        (cons (deref x) (step xs (rest s)))
                        (map deref vs))))]
         (step rets (drop n rets)))))
  ([num-threads f coll & colls]
     (let [step (fn step [cs]
                  (lazy-seq
                    (let [ss (my-lazy-map seq cs)]
                      (when (every? identity ss)
                        (cons (my-lazy-map first ss)
                              (step (my-lazy-map rest ss)))))))]
       (modified-pmap num-threads #(apply f %) (step (cons coll colls))))))
  

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


(defn do-mandelbrot [size num-threads]
  (let [rows (compute-rows size num-threads)]
    (println "P4")
    (println (format "%d %d" size size))
    (let [ostream (BufferedOutputStream. System/out)]
      (doseq [r rows]
        (. ostream write (into-array Byte/TYPE r) 0 (count r)))
      (. ostream close))
    (flush)))


(def *default-modified-pmap-num-threads*
     (+ 2 (.. Runtime getRuntime availableProcessors)))

(defn usage [exit-code]
  (println (format "usage: %s size [num-threads]"
                   *file*))
  (println (format "    size must be a positive integer"))
  (println (format "    num-threads is the maximum threads to use at once"))
  (println (format "        during the computation.  If 0 or not given, it"))
  (println (format "        defaults to the number of available cores plus 2,"))
  (println (format "        which is %d"
                   *default-modified-pmap-num-threads*))
  (. System (exit exit-code)))


(defn -main [& args]
  (when (or (< (count args) 1) (> (count args) 2))
    (usage 1))
  (when (not (re-matches #"^\d+$" (nth args 0)))
    (usage 1))
  (def size (. Integer valueOf (nth args 0) 10))
  (when (< size 1)
    (usage 1))
  (def num-threads
       (if (>= (count args) 2)
         (do
           (when (not (re-matches #"^\d+$" (nth args 1)))
             (usage 1))
           (let [n (. Integer valueOf (nth args 1) 10)]
             (if (== n 0)
               *default-modified-pmap-num-threads*
               n)))
         *default-modified-pmap-num-threads*))
  (do-mandelbrot size num-threads)
  (. System (exit 0)))

 make, command-line, and program output logs

Sat, 18 Aug 2012 04:48:50 GMT

MAKE:
mv mandelbrot.clojure-2.clojure mandelbrot.clj
/usr/local/src/jdk1.7.0_06/bin/java -Dclojure.compile.path=. -cp .:/usr/local/src/clojure-1.4.0/clojure-1.4.0-slim.jar clojure.lang.Compile mandelbrot
Compiling mandelbrot to .
Warning: *default-modified-pmap-num-threads* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *default-modified-pmap-num-threads* or change the name. (mandelbrot.clj:134)
5.57s to complete and log all make actions

COMMAND LINE:
/usr/local/src/jdk1.7.0_06/bin/java -server -XX:+TieredCompilation -XX:+AggressiveOpts -XX:+UseBiasedLocking -Xmx128m -cp .:/usr/local/src/clojure-1.4.0/clojure-1.4.0-slim.jar mandelbrot 16000

(BINARY) PROGRAM OUTPUT NOT SHOWN

Revised BSD license

  Home   Conclusions   License   Play