静态方法很慢

时间:2012-11-22 22:59:04

标签: java performance

我正在用java编写一个简单的游戏。 我用30 FPS进行了碰撞测试,我必须得到窗口的大小。 因为我没有访问GUI实例,所以我认为我会创建一个共享实例,因为这在Objective-C中非常标准,我来自。

class GUI extends JFrame {
    private static GUI _sharedInstance;

    public static GUI sharedInstance() {
        if (_sharedInstance == null) {
            _sharedInstance = new GUI();
        }
        return _sharedInstance;
    }
}

但出于某种原因,它确实很慢。 然后我用大小的public static final个实例替换了共享实例,它现在可以快速运行,即使是60 FPS或更高。

任何人都可以解释为什么会这样吗?

修改

因此,我只是致电GUI.sharedInstance().getWidth()而不是致电GUI.windowSize.width。 我改为使用了public static final Dimension windowSize

修改

这是碰撞检测。 所以,而不是调用int width = GUI.kWindowWidth;, 我之前打电话给int width = GUI.sharedInstance().getWidth();

// 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));
    }
}

1 个答案:

答案 0 :(得分:3)

我知道这可能不是这个问题的真正答案,但是竞争条件可能存在问题。 我假设你正在尝试使用lazy / singleton模式,因为GUI类的构造非常昂贵而且你只需要一个实例。

现在,会发生什么?如果一个线程进入if语句体,它会创建一个新的GUI实例。在下一次分配之前,它会被调度程序暂停。 现在弹出另一个线程,看到_sharedInstance仍为null并创建另一个GUI实例(依此类推......)。

让我们假设只有两个线程。 第一个线程运行到结束,第二个线程继续运行,现在您有两个GUI类实例。没有人说未分配的GUI实例被破坏或被垃圾收集。 与最终使用并将GUI实例直接分配给_sharedInstance相比,这可以解释50%的性能损失。

参见例如http://en.wikipedia.org/wiki/Singleton_pattern处的Java示例 双重检查锁定,内部类或枚举是您可以使用的方式。