3

假设我想编写一个 ocr 算法。因此我想创建一个二进制图像。使用 clojure 和 quil 我想出了:

(defn setup []

  (load-pixels)

  (let [pxls (pixels)
             ]
    (letfn [(pxl-over-threshold? [idx] (if (> (red (aget pxls idx)) 128) true false))
            ]
           (time (dotimes [idx 25500] (aset pxls idx (color (rem idx 255)))))

           (time (dotimes [idx 25500] (if (pxl-over-threshold? idx)
                                          (aset pxls idx (color 255))
                                          (aset pxls idx (color 0)))))))
  (update-pixels))

(defn draw [])

(defsketch example
  :title "image demo"
  :setup setup
  :draw draw
  :size [255 100]
  :renderer :p2d)

;"Elapsed time: 1570.58932 msecs"
;"Elapsed time: 2781.334345 msecs" 

该代码生成灰度,然后遍历所有像素以将它们设置为黑色或白色。它执行请求的行为,但需要大约 4.3 秒才能到达那里(1.3 双核)。我没有参考将 4.3 秒放在上下文中。但是考虑处理更大的图像,这必须变得非常慢。

我是在做一些非常错误的事情还是有办法解决问题?clojure 和 quil 的组合甚至能够更快地进行像素转换,还是我应该选择不同的语言/环境?

如果我在代码中做一些奇怪的事情,也请告诉我。我还是clojure的新手。

提前致谢。

4

1 回答 1

3

您所采用的时间并不是特别有意义,因为代码还没有暖和。您需要“预热”代码,以便 JVM 对其进行 JIT 编译,这时您应该开始看到良好的速度。你应该看看如何在 Clojure 中对函数进行基准测试?(您应该使用Criterium。)

至于您的代码,您使用的是数组,因此应该会给您带来良好的性能。风格方面,]你有两个悬挂真的很奇怪。也许这只是一个格式错误?消除尽可能多的重复代码通常很好,所以我也会改变这个

(if (pxl-over-threshold? idx)
  (aset pxls idx (color 255))
  (aset pxls idx (color 0)))

对此

(aset pxls idx (color (if (pxl-over-threshold? idx) 255 0)))

如果你觉得看起来太混乱/复杂(我有点想知道我是否认为这太难读了),你也可以用以下任何一种方式来写:

(let [c (if (pxl-over-threshold? idx) 255 0)]
  (aset pxls idx (color c)))

(->> (if (pxl-over-threshold? idx) 255 0) color (aset pxls idx))
于 2013-09-18T05:34:27.127 回答