在 Java 中优化绘图方法
Optimizing Draw Method in Java
我有一个 mandlebrot 程序可以在屏幕上绘制 mandlebrot 分形。我有一个显示计算速度的计时器,范围为 0 - 10 毫秒。我有一个 draw(Graphics2D g) 方法,可以在屏幕上绘制二维像素数组。计时器显示 draw 方法大约需要 100 毫秒,并且随着缩放的增加,逐渐增加到大约 700 毫秒。 draw 方法被连续调用,而 mandlebrot 计算方法仅在 mandlebrot 移动或放大时调用。这是我的 draw 方法代码:
public void draw(Graphics2D g) {
// col and row pixel positions of the pixel being drawn
// The if statements check if the point is in the mandlebrot set
// I added a 3 dimensional array just so it could store the color number, and 0 or 1 if it's in the mandlebrot set
// g.drawLine() draws the pixel at it's location
for(int col = 0; col < 640; col++) {
for(int row = 0; row < 480; row++) {
if(Mandlebrot.pixels[col][row][0] == 1) {
g.setColor(new Color(Mandlebrot.pixels[col][row][1]));
g.drawLine(col, row, col, row);
} else {
g.setColor(Color.BLACK);
g.drawLine(col, row, col, row);
}
}
}
}
我在想也许 BufferedImage 会更快,但是当我尝试它时,我遇到了一些奇怪的屏幕故障。我也在考虑尝试让多个线程同时渲染屏幕的一部分。因此,也许 1 个线程绘制从 (0,0) 到 (100,100) 的像素,另一个线程绘制从 (0,100) 到 (100,200) 的像素,依此类推。有没有更好的方法来做到这一点,延迟肯定是由 draw 方法引起的吗?还是有别的东西阻碍了它?当调用计算方法时,程序会启动大约 10 个线程来计算屏幕的各个部分,这会稍微提高性能。线程在完成时终止。
这是当前程序的可运行 jar:
http://www.mediafire.com/download/uh93231z71q27y1/Mandlebrot.jar
drawline方法比较耗时,最好用BufferedImage,调用
image.setRGB(int x, int y, int rgb)
对于您需要绘制的所有像素
编辑: 因为有人想查看我所说内容的指标,所以这是从我创建的应用程序中获取的时间,我的代码正在做一些非常相似的事情(循环一个表示像素的数组,并用一种颜色绘制每个像素)。使用 System.currentTimeMillis();
每个计时以毫秒为单位
与graphics.drawLine:
Time : 71
Time : 66
Time : 71
Time : 66
Time : 68
Time : 66
Time : 68
Time : 68
Time : 69
Time : 65
Time : 67
Time : 68
Time : 75
与 image.setRGB:
Time : 58
Time : 44
Time : 43
Time : 41
Time : 45
Time : 45
Time : 45
Time : 45
Time : 44
Time : 45
Time : 46
Time : 45
Time : 45
我有一个 mandlebrot 程序可以在屏幕上绘制 mandlebrot 分形。我有一个显示计算速度的计时器,范围为 0 - 10 毫秒。我有一个 draw(Graphics2D g) 方法,可以在屏幕上绘制二维像素数组。计时器显示 draw 方法大约需要 100 毫秒,并且随着缩放的增加,逐渐增加到大约 700 毫秒。 draw 方法被连续调用,而 mandlebrot 计算方法仅在 mandlebrot 移动或放大时调用。这是我的 draw 方法代码:
public void draw(Graphics2D g) {
// col and row pixel positions of the pixel being drawn
// The if statements check if the point is in the mandlebrot set
// I added a 3 dimensional array just so it could store the color number, and 0 or 1 if it's in the mandlebrot set
// g.drawLine() draws the pixel at it's location
for(int col = 0; col < 640; col++) {
for(int row = 0; row < 480; row++) {
if(Mandlebrot.pixels[col][row][0] == 1) {
g.setColor(new Color(Mandlebrot.pixels[col][row][1]));
g.drawLine(col, row, col, row);
} else {
g.setColor(Color.BLACK);
g.drawLine(col, row, col, row);
}
}
}
}
我在想也许 BufferedImage 会更快,但是当我尝试它时,我遇到了一些奇怪的屏幕故障。我也在考虑尝试让多个线程同时渲染屏幕的一部分。因此,也许 1 个线程绘制从 (0,0) 到 (100,100) 的像素,另一个线程绘制从 (0,100) 到 (100,200) 的像素,依此类推。有没有更好的方法来做到这一点,延迟肯定是由 draw 方法引起的吗?还是有别的东西阻碍了它?当调用计算方法时,程序会启动大约 10 个线程来计算屏幕的各个部分,这会稍微提高性能。线程在完成时终止。
这是当前程序的可运行 jar: http://www.mediafire.com/download/uh93231z71q27y1/Mandlebrot.jar
drawline方法比较耗时,最好用BufferedImage,调用
image.setRGB(int x, int y, int rgb)
对于您需要绘制的所有像素
编辑: 因为有人想查看我所说内容的指标,所以这是从我创建的应用程序中获取的时间,我的代码正在做一些非常相似的事情(循环一个表示像素的数组,并用一种颜色绘制每个像素)。使用 System.currentTimeMillis();
每个计时以毫秒为单位与graphics.drawLine:
Time : 71
Time : 66
Time : 71
Time : 66
Time : 68
Time : 66
Time : 68
Time : 68
Time : 69
Time : 65
Time : 67
Time : 68
Time : 75
与 image.setRGB:
Time : 58
Time : 44
Time : 43
Time : 41
Time : 45
Time : 45
Time : 45
Time : 45
Time : 44
Time : 45
Time : 46
Time : 45
Time : 45