2

だから私はclojureで基本的な画像処理を行ってきました(RGBをグレースケールに変換するだけです)、amapに深刻な問題があります。つまり、私はそれを速くすることができません。

型ヒントで21000ミリ秒から8000ミリ秒程度まで下げることができましたが、それだけです。対照的に、法線マップは約 400ms で実行されます...

このような単純な操作をできるだけ速くするために、他にできることはありますか?

(defn setpxl [^BufferedImage image data]
  (let [h (.getHeight image)
    w (.getWidth image)]
  (.setRGB image 0 0 w h ^ints data 0 w)
) )

(defn getrgb [rgb]
 (let [r  (bit-shift-right (bit-and rgb (int 0x00FF0000)) 16)
    g  (bit-shift-right (bit-and rgb (int 0x0000FF00)) 8)
    b  (bit-and rgb (int 0x000000FF))]
[r g b])
)

(defn graycalc [[r g b]]
  (let [gray (int (/ (+ r g b) 3))
    r  (bit-shift-left gray 16)
    g  (bit-shift-left gray 8)
    b  gray
    a  (bit-shift-left 0x00 24)
    ]
  (int (bit-or a r g b))))

(defn testrgb []
  (let [img (time (javax.imageio.ImageIO/read (as-file "D:/cat.jpg")))
    h (.getHeight img)
    w (.getWidth img)
    arr (time (int-array (getpxl img)))
    gray (time
          ;;why is amap so slow?

          ;;400ms
          (int-array (map #(graycalc (getrgb %1)) arr))

          ;;8000ms
          ;; (amap ^ints arr idx ret (graycalc (getrgb (aget ^ints arr idx))))
          )

    frame (JFrame. "grayscale image")
    label (JLabel. (ImageIcon. img))
    panel (.getContentPane frame)]

(-> panel (.add label))
(.setSize frame w h)
(.setVisible frame true)

(time (setpxl img gray))
(.repaint panel)
)

)

4

1 に答える 1

3

サンプルを実行するためにコードを少しずつ追加する必要があったため、最初に結果として得られた要点を次に示します。

どういうわけか、リフレクションが開始されているように感じました。get が全速力で動作するには、型に関する少しの助けが必要だからです。ここに関連するSO スレッドがあります。

使用:

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

戻ってきた:

 Reflection warning, core.clj:46:11 - call to aset can't be resolved.

ファイルをロードするとき。

結局のところ、各ピクセルで使用される関数には戻り値の型がありませんでした。次のようにして、型をコードに追加できます。

 (amap ^ints arr idx ret (graycalc (getrgb (aget ^ints arr idx))))

の中へ:

 (amap ^ints arr idx ret ^int (graycalc (getrgb (aget ^ints arr idx))))

aset は配列の各値で使用されるため、型のヒントがないと、呼び出しは配列の各値でリフレクションを利用していました。

スピードランは次のようになります。

 imaging.core=> (load-file "src/imaging/core.clj")
 Reflection warning, core.clj:45:11 - call to  aset can't be resolved.
 #'imaging.core/testrgb
 imaging.core=> (testrgb)
 "Elapsed time: 107.138 msecs"
 "Elapsed time: 359.448 msecs"
 "Elapsed time: 44267.634 msecs"
 "Elapsed time: 92.022 msecs"
 nil
 imaging.core=> (load-file "src/imaging/core.clj")
 #'imaging.core/testrgb
 imaging.core=> (testrgb)
 "Elapsed time: 102.871 msecs"
 "Elapsed time: 423.294 msecs"
 "Elapsed time: 1377.818 msecs"
 "Elapsed time: 88.026 msecs"

速度の参考のために、マップは次の場所で実行されています。

 "Elapsed time: 2903.577 msecs"

および pmap:

 "Elapsed time: 9351.502 msecs"
于 2013-10-06T01:18:40.290 に答える