Java非常慢的方法

时间:2013-04-08 15:42:24

标签: java

我注意到我的一个方法非常慢,通过分析我注意到它占用了总执行时间的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坐标上循环。

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

有关

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

1 个答案:

答案 0 :(得分:0)

试试这个:如果redgreenblue没有改变,那么停止使用匿名类,并在你实现的子类中执行:(注意,这可能不起作用,但基本的想法应该是,如果你可以通过缓存你可能需要的所有颜色来避免不断调用new 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]);
}