当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 寻找一种逐像素绘制的快速方法,为什么这段代码比java慢1000倍?

来源:互联网 收集:自由互联 发布时间:2021-06-22
这是一个简单的代码,只对窗口着色4次. 也许有一些我看不到的明显事物. 我的目标是从头开始学习计算机图形,我想逐个像素地绘制以完全控制.我正在寻找一种快速的方法来做到这一点
这是一个简单的代码,只对窗口着色4次.

也许有一些我看不到的明显事物.

我的目标是从头开始学习计算机图形,我想逐个像素地绘制以完全控制.我正在寻找一种快速的方法来做到这一点.

Here是完整代码.

相关的clojure部分:

(defmacro for-loop [[sym init check change :as params] & steps]
  `(loop [~sym ~init value# nil]
     (if ~check
       (let [new-value# (do ~@steps)]
         (recur ~change new-value#))
       value#)))
(time
 (for-loop
  [k 0 (< k 2) (inc k)]
  (for-loop
   [c 0 (< c 2) (inc c)]
   (for-loop
    [i 0 (< i width) (inc i)]
    (for-loop
     [j 0 (< j height) (inc j)]
     (aset ^ints @pixels (+ i (* j width)) (get cs c))))
   (.repaint canvas))))

java中的相同代码:

long t = System.currentTimeMillis();
for (int k = 0 ; k < 2; k++) {
  for (int c = 0; c < 2; c++) {
    for (int i = 0 ; i < width; i++) {
      for (int j = 0; j < height; j++) {
        pixels[i + j * width] = cs[c];
      }
    }
    repaint();
  }
}
System.out.println(System.currentTimeMillis() - t);
有几个问题:

>如果你运行lein检查,你会看到反射警告.你在运行时强制反射会降低速度.我将画布创建更改为:

(defonce canvas (doto (proxy [Frame] []
                        (update [g] (.paint this g))
                        (paint [^Graphics2D g]
                          (.drawImage g, ^BufferedImage image, 0, 0 nil)))
                  (.setSize width height)
                  (.setBackground Color/black)
                  (.setFocusableWindowState false)
                  (.setVisible true)))

注意我正在使用的类型提示.它不知道要使用哪个drawImage重载,并且完全找不到paint方法.
>然而,主要问题是使用aset.来自aset的文档:

Sets the value at the index/indices. Works on Java arrays of
reference types.
Returns val.

强调我的.

问题是aset不适用于原语.它强制将每个数字包装为整数,然后在图像中使用时再次打开.当在图像的每个像素上相乘时,这是非常昂贵的.

将aset更改为aset-int以改为使用int基元.这将执行时间从大约20秒缩短到半秒.

老实说,我不能低估它.它比它快得多,但仍然比Java版本慢约20倍.我现在已经工作了将近2个小时,而且我已经撞墙了.希望其他人可以挤出最后一点时间.

网友评论