I'm programming a simple game in java. I've made a collision test with 30 FPS, where I had to get the size of the window. Because I haven't had access to the GUI instance, I thought I'd make a shared instance, because this is pretty standard in Objective-C, where I come from.
class GUI extends JFrame {
private static GUI _sharedInstance;
public static GUI sharedInstance() {
if (_sharedInstance == null) {
_sharedInstance = new GUI();
}
return _sharedInstance;
}
}
But for some reason, it was really slow.
Then I replaced the shared instance with public static final
instances for the size, and it works fast now, even with 60 FPS or higher.
Can anyone explain me why this happens?
EDIT
So instead of calling GUI.sharedInstance().getWidth()
, I'm just calling GUI.windowSize.width
.
I have used the public static final Dimension windowSize
instead.
EDIT
Here's the collision detection.
So, instead of calling int width = GUI.kWindowWidth;
,
I was calling int width = GUI.sharedInstance().getWidth();
before.
// Appears on other side
if (kAppearsOnOtherSide) {
int width = GUI.kWindowWidth;
int height = GUI.kWindowHeight;
// Slow
// int width = GUI.sharedInstance().getWidth();
// int width = GUI.sharedInstance().getHeight();
Point p = this.getSnakeHead().getLocation();
int headX = p.x;
int headY = p.y;
if (headX >= width) {
this.getSnakeHead().setLocation(new Point(headX - width, headY));
} else if (headX < 0) {
this.getSnakeHead().setLocation(new Point(headX + width, headY));
} else if (headY >= height) {
this.getSnakeHead().setLocation(new Point(headX, headY - height));
} else if (headY < 0) {
this.getSnakeHead().setLocation(new Point(headX, headY + height));
}
}
I know that this might not be the real answer to the question, but there could be a problem with a race condition. I assume that you are trying to use the lazy/singleton pattern, because the construction of the GUI class is quite expensive and you need only one instance.
Now, what happens? If a thread runs into the if
statement body, it creates a new GUI
instance. Just before the next assignment, it gets paused by the scheduler.
Now another thread pops in, sees that _sharedInstance
is still null and creates another GUI
instance (and so on...).
Lets assume that there are only two threads.
The first thread runs to the end and the second one is continued, now you have two instances of the GUI class. Nobody says that the unassigned GUI instance gets destroyed or garbage collected.
That could explain tha 50 % performance loss compared to using finally and assigning the GUI instance directly to _sharedInstance
.
See e.g. the Java examples at http://en.wikipedia.org/wiki/Singleton_pattern Double checked locking, inner classes or an enum are the ways you can use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With