Java awt 性能焦虑
有一个程序可以在屏幕上同时生成数百或数千个移动粒子。显示数百个后,速度就会变慢。使用 netbeans profiler 分析性能,大约 80% 的时间花在 jpanel 的 Paint 方法上……所以算法优化似乎不太可能产生明显的差异。对此有什么可以做的吗?或者是时候考虑一个新平台了?绘制方法看起来像这样:
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
for (int i = 0; i < gameLogic.getParticleArrSize(); i++) {
g.setColor(gameLogic.getParticleColor(i));
g.fillOval(gameLogic.getParticleXCoor(i),
gameLogic.getParticleYCoor(i),
gameLogic.getParticleSize(i),
gameLogic.getParticleSize(i));
}
g.setColor(gameLogic.getCurrPartColor());
g.fillOval(mouseX - mouseOvalRadius, mouseY - mouseOvalRadius,
mouseOvalSize, mouseOvalSize);
g.setColor(gameLogic.getCursorColor());
g.fillOval(mouseX - 19, mouseY - 19, 38, 38);
for (int i = 0; i < gameLogic.getBombArrSize(); i++) {
g.setColor(Color.RED);
g.fillOval(gameLogic.getBombXCoor(i) - 6,
gameLogic.getBombYCoor(i) - 6,
gameLogic.getBombSize(i),
gameLogic.getBombSize(i));
}
for (int i = 0; i < gameLogic.getPowerUpParticleArrSize(); i++) {
g.setColor(gameLogic.getPowerUpParticleColor(i));
g.fillOval(gameLogic.getPowerUpParticleXCoor(i),
gameLogic.getPowerUpParticleYCoor(i),
gameLogic.getPowerUpParticleSize(i),
gameLogic.getPowerUpParticleSize(i));
}
for (int i = 0; i < gameLogic.getBlackArrSize(); i++) {
g.setColor(Color.BLACK);
g.fillOval(gameLogic.getBlackParticleXCoor(i),
gameLogic.getBlackParticleYCoor(i),
gameLogic.getBlackParticleSize(i),
gameLogic.getBlackParticleSize(i));
}
}
There is a program that generates hundreds or thousands of moving particles onscreen at once. After several hundred are displayed, slowdown occurs. Performance was analyzed using netbeans profiler and about 80% of the time was spend in the jpanel's paint method...so algorithm optimization seems unlikely to make a noticeable difference. Is there anything that can be done about this or is it time to think about a new platform? The paint method looks something like this:
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
for (int i = 0; i < gameLogic.getParticleArrSize(); i++) {
g.setColor(gameLogic.getParticleColor(i));
g.fillOval(gameLogic.getParticleXCoor(i),
gameLogic.getParticleYCoor(i),
gameLogic.getParticleSize(i),
gameLogic.getParticleSize(i));
}
g.setColor(gameLogic.getCurrPartColor());
g.fillOval(mouseX - mouseOvalRadius, mouseY - mouseOvalRadius,
mouseOvalSize, mouseOvalSize);
g.setColor(gameLogic.getCursorColor());
g.fillOval(mouseX - 19, mouseY - 19, 38, 38);
for (int i = 0; i < gameLogic.getBombArrSize(); i++) {
g.setColor(Color.RED);
g.fillOval(gameLogic.getBombXCoor(i) - 6,
gameLogic.getBombYCoor(i) - 6,
gameLogic.getBombSize(i),
gameLogic.getBombSize(i));
}
for (int i = 0; i < gameLogic.getPowerUpParticleArrSize(); i++) {
g.setColor(gameLogic.getPowerUpParticleColor(i));
g.fillOval(gameLogic.getPowerUpParticleXCoor(i),
gameLogic.getPowerUpParticleYCoor(i),
gameLogic.getPowerUpParticleSize(i),
gameLogic.getPowerUpParticleSize(i));
}
for (int i = 0; i < gameLogic.getBlackArrSize(); i++) {
g.setColor(Color.BLACK);
g.fillOval(gameLogic.getBlackParticleXCoor(i),
gameLogic.getBlackParticleYCoor(i),
gameLogic.getBlackParticleSize(i),
gameLogic.getBlackParticleSize(i));
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
什么时候触发repaint()?是否在某个时间间隔上设置了计时器?我创建了一个动画库,并且能够顺利地为 40 个项目制作动画。您可能有更多对象,但我会首先查看时间间隔。
编辑:
好的,这是我的建议。首先,您需要弄清楚绘图中的哪个功能占用了最多的时间。看来您经常调用 fillOval 。我的建议是使用以下内容创建一次形状:new RoundRectangle2D.Double()。然后使用 AffineTransformation 来移动形状。我很想知道其他人有什么建议,所以我会回来查看。
When are you triggering repaint()? Is it set on a timer on some time interval? I created an animation lib and I was able to animate 40 items smoothly. You probably have many more objects but I would look at the time interval first.
Edit:
Ok so here is my suggestion. First you need to figure out which function in paint is taking the most amount of time. It seems like you are calling fillOval a lot. My suggestion would be to create the shape once using something like: new RoundRectangle2D.Double(). And then use AffineTransformation to move around the shapes instead. I am curious to know what other suggest, so I will check back.
尝试探索 Graphics2D 库。任何形状的填充算法,即使是像椭圆形这样简单的形状,都是昂贵的。创建形状、填充它然后将其复制到其他位置要快得多。 2D 库还支持各种缩放变换等。
这与 Daniel Viona 的 sprite 建议非常相似。精灵的存在是有原因的 - 它们是绘制许多简单小对象的快速方法!
如果我有时间,我会尝试画 1000 个小物体 - 介意了解这些物体的尺寸范围吗?就几个像素?我猜能量提升和炸弹相对较少,只有粒子会伤害你,对吧......
Try exploring the Graphics2D library. The fill algorithm for any shape, even something as simple as an oval, is expensive. It is far faster to create a shape, fill it then copy it to other locations. The 2D library also supports various transforms for scaling etc.
This is very similar to Daniel Viona's sprite suggestion. Sprites exist for a reason - they are a fast way to draw many small simple objects!
If I get some time I will try to draw 1000's of small objects - care to give an idea of the size range these objects will have? Just a few pixels? I am guessing the power ups and bombs are relative few, it is only the particles that are hurting you right...
,因为绝大多数处理都是单线程的,这意味着在现代机器上至少有一个 CPU 核心几乎完全被浪费了。如今,大多数计算机至少有双核,甚至更多。有几种方法可以让您利用这一点:
作为奖励...如果您确实想要性能,请考虑 JOGL。请参阅此处的示例:
Since the vast majority of your processing is single-threaded, that means at least one CPU core is being almost entirely wasted on modern machines. Most computers have at least dual-cores these days, if not more. There are a couple ways for you to take advantage of this:
As a bonus note... If you really want performance, consider JOGL. Look here for an example: