0

我注意到我的一种方法非常慢,通过分析我注意到它占用了总执行时间的 95%。

班上:

package gui;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

/**
 *
 * @author Frank
 */
public abstract class CustomRectangle {
    protected final BufferedImage bufferedImage;
    protected final int width;
    protected final int height;
    protected final int xOffset;
    protected final int yOffset;
    protected final int borderSize;
    protected final boolean defaultOrientation;

    protected Color color;

    public CustomRectangle(final BufferedImage bufferedImage, final int width, final int height, final int xOffset, final int yOffset, final int borderSize, final boolean defaultOrientation) {
        this.bufferedImage = bufferedImage;
        this.width = width;
        this.height = height;
        if (defaultOrientation) {
            this.xOffset = xOffset;
            this.yOffset = yOffset;
        }
        else {
            this.xOffset = bufferedImage.getWidth() - 1 - xOffset;
            this.yOffset = bufferedImage.getHeight() - 1 - yOffset;
        }
        this.borderSize = borderSize;
        this.defaultOrientation = defaultOrientation;
    }

    abstract public void inBorder(final int dx, final int dy);

    abstract public void outBorder(final int dx, final int dy);

    public void draw() {
        if (defaultOrientation) {
            drawDefaultOrientation();
        }
        else {
            drawOppositeOrientation();
        }
    }

    private void drawDefaultOrientation() {
        int[] pixelArray = ((DataBufferInt)bufferedImage.getRaster().getDataBuffer()).getData();
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int dx = Math.min(x, width - 1 - x);
                int dy = Math.min(y, height - 1 - y);
                if (dx < borderSize || dy < borderSize) {
                    inBorder(dx, dy);
                }
                else {
                    outBorder(dx, dy);
                }
                pixelArray[(xOffset + x) + ((yOffset + y) * bufferedImage.getWidth())] = color.getRGB();
            }
        }
    }    

    private void drawOppositeOrientation() {
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int dx = Math.min(x, width - 1 - x);
                int dy = Math.min(y, height - 1 - y);
                if (dx < borderSize || dy < borderSize) {
                    inBorder(dx, dy);
                }
                else {
                    outBorder(dx, dy);
                }
                bufferedImage.setRGB(xOffset - x, yOffset - y, color.getRGB());              
            }
        }
    }  

    public void setColor(final Color color) {
        this.color = color;
    }
}

缓慢的方法是 drawDefaultOrientation() 方法。然而,可怕的是,即使我省略了所有图像修改代码,它仍然很慢。

被调用者代码:

    new CustomRectangle(bufferedImage, 440, 180, 30, 490, 10, defaultOrientation) {
        @Override
        public void inBorder(final int dx, final int dy) {
            setColor(new Color(red, green, blue, 255 - (int)Math.round(0.5 * Math.min(dx, dy))));
        }

        @Override
        public void outBorder(final int dx, final int dy) {
            setColor(new Color(red, green, blue, 128 - (int)Math.round(0.5 * Math.min(dx, dy))));
        }
    }.draw(); 

一定有什么事情发生了,因为无论如何这段代码都不应该花这么长时间,即使它在 x 和 y 坐标上循环。

有人认为我认为它可能与匿名内部类 + 覆盖有关......

但希望有更多知识的人可以回答这个问题。

4

1 回答 1

0

试试这个:如果red,,不要改变,然后停止使用匿名类,并在你实现的子类中做:(注意,这可能不起作用,但基本想法应该是,如果你可以通过缓存所有颜色来避免green不断调用你可能需要)bluenew Color

private final Color[] colors;

public ImplementedCustomRectangle(...) {
    super(...); // ... is not real code, I just don't want to copy/paste

    colors = new Color[256];
    for (i = 0; i < 256; i++) {
        colors[i] = new Color(red, green, blue, i);
    }
}

@Override
public void inBorder(final int dx, final int dy) {
    int value = 255 - (int)Math.round(0.5 * Math.min(dx, dy));
    setColor(colors[value]);
}

@Override
public void outBorder(final int dx, final int dy) {
    int value = 128 - (int)Math.round(0.5 * Math.min(dx, dy);
    setColor(colors[value]);
}
于 2013-04-08T16:09:04.847 回答