Mandelbrot设置功能未按预期执行

时间:2015-05-12 21:42:16

标签: performance clojure

以下是Clojure Programming Paperback by Chas Emerick:

的示例
(import 'java.awt.image.BufferedImage
        '(java.awt Color RenderingHints))

(defn- escape
  [^double a0 ^double b0 ^long depth]
  (loop [a a0, b b0, iteration 0]
    (cond
      (< 4 (+ (* a a) (* b b))) iteration
      (>= iteration depth) -1
      :else (recur (+ a0 (- (* a a) (* b b)))
                   (+ b0 (apply * [2 a b]))
                   (inc iteration)))))

(defn mandelbrot [rmin rmax imin imax
                  & {:keys [width height depth]
                     :or   {width 80 height 40 depth 1000}}]
  (let [mandelbrot-help
        (fn [^double rmin ^double rmax
             ^double imin ^double imax
             ]
          (let [stride-w (/ (- rmax rmin) width)
                stride-h (/ (- imax imin) height)]
            (loop [x 0
                   y (dec height)
                   escapes []]
              (if (== x width)
                (if (zero? y)
                  (partition width escapes)
                  (recur 0 (dec y) escapes))
                (recur (inc x) y (conj escapes
                                       (escape (+ rmin (* x stride-w))
                                               (+ imin (* y stride-h))
                                               depth)))))))]
    (mandelbrot-help rmin rmax imin imax)))

(defn render-text
  [mandelbrot-grid]
  (doseq [row mandelbrot-grid]
    (doseq [escape-iter row]
      (print (if (neg? escape-iter)
               \*
               \space)))
    (println)))

(defn render-image
  [mandelbrot-grid]
  (let [palette
        (vec (for
               [c (range 500)]
               (Color/getHSBColor 0.0 0.0 (/ (Math/log c) (Math/log 500)))))
        height (count mandelbrot-grid)
        width (count (first mandelbrot-grid))
        img (BufferedImage. width height BufferedImage/TYPE_INT_RGB)
        ^java.awt.Graphics2D g (.getGraphics img)]
    (doseq [[y row] (map-indexed vector mandelbrot-grid)
            [x escape-iter] (map-indexed vector row)]
      (.setColor g (if (neg? escape-iter)
                     (palette 0)
                     (palette (mod (dec (count palette)) (inc escape-iter)))))
      (.drawRect g x y 1 1))
    (.dispose g)
    img))


(do (time (mandelbrot -2.25 0.75 -1.5 1.5
                      :width 1600 :height 1200 :depth 1000))
    nil)

除了在我的机器上花费60秒,并且根据书中只有8秒(在我的笔记本电脑上的结果在其他示例中始终更好)之外,一切都有效。

我做错了吗?

1 个答案:

答案 0 :(得分:4)

你从哪里获得该代码?绝对不是书中出现的内容(基于我的PDF副本,第449-452页)或code sample on github。特别是escape中的escape 疯狂;这永远不会很快(至少没有任何程度的[平凡]源级优化,但不幸的是Clojure并不适用)。甚至更奇怪,那个特定的片段并没有出现在书中的任何地方,我也无法在我们曾经合作撰写本书的git repo的历史中找到它。

也许你只是在修补这些例子?如果没有,我真的想知道你的样本来自哪里,因为它绝对不能代表我们的意图或最佳实践(显然,考虑到你所看到的时间)。

无论如何,这里是&#34;快速(defn- escape [^double a0 ^double b0 depth] (loop [a a0 b b0 iteration 0] (cond (< 4 (+ (* a a) (* b b))) iteration (>= iteration depth) -1 :else (recur (+ a0 (- (* a a) (* b b))) (+ b0 (* 2 (* a b))) (inc iteration))))) user> (do (time (mandelbrot -2.25 0.75 -1.5 1.5 :width 1600 :height 1200 :depth 1000)) nil) "Elapsed time: 1987.460104 msecs" &#34;函数来自book / github样本repo:

depth

^long arg暗示为JacksonJsonProvider(本书中应该包含的内容)在我的笔记本电脑上将其降至1450毫秒。