2013-04-08 7 views
0

Я заметил, что один из моих методов работает очень медленно, с профилированием я заметил, что это заняло 95% от общего времени выполнения.Java очень медленный метод

Класс:

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(); 

Там должно быть что-то происходит, как и в любом случае этот код не должен принимать это долго, даже если он перебирает х и у координат.

Некоторые мысли у меня было, что она могла бы сделать с Anonymous внутренний класс + Override ...

Но, надеюсь, кто-то с большим знанием может ответить на этот вопрос.

+6

Принимая 95% от общего времени выполнения не означает, что метод является медленным. Это означает, что ваша программа проводит большую часть своего времени в этом методе. 'main()' принимает 100% общего времени выполнения в однопоточной программе. –

+1

Возможно, я сформулировал это неправомерно. Я больше имею в виду, что он использует 95% исполнения, но в то время он не делает ничего полезного. – skiwi

+0

Что делают 'inborder' и' outborder'? Кроме того, похоже, что вы можете переместить вызов 'color.getRGB()' вне цикла. –

ответ

0

Попробуйте это: Если red, green, blue не изменится, то прекратите использовать анонимный класс, и в вашем реализованного подклассу сделать: (обратите внимание, что это не может работать, но основная идея должна, если вы можете избежать постоянно вызывая 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]); 
} 
Смежные вопросы