许多简单类实例,是我的实践最好的解决方案吗?

时间:2014-04-02 19:57:10

标签: java performance class object instance

我正在开发一款使用Vector2类来执行所需计算的游戏。 这是一个你可以想象的简单类:字段“x”,“y”,一些方法,如add(),sub(),scl()

如果我正在创建这样的方法:

public void doSomething() {
    Vector2 offset = new Vector2(10, 3);
    offset.rotate(45).add(3, 2);

    Vector2 position = new Vector2(20, 35);
    position.sub(4, 5).add(offset);

    // something else
}

创建了很多Vector2类实例,GC有很多工作要做,在一个游戏步骤(1/40秒)中创建了200多个向量。因此,当GC运行时,游戏FPS正在下降。

我尝试使用池来回收创建的实例,但这是非常糟糕的错误,收集和处理它们比GC花了更多的时间。

所以我想预先创建实例并使用它们:

private final Vector2 v1 = new Vector2(), v2 = new Vector2();
public void doSomething() {

    Vector2 offset = v1;
    offset.set(10, 3);
    offset.rotate(45).add(3, 2);

    Vector2 position = v2;
    position.set(20, 35);
    position.sub(4, 5).add(offset);

    // something else
}

v1和v2是类字段,它们在创建对象时实例化一次。 通过这种方式,我实现了性能并为变量保留了友好名称。

然而,我想知道它是否是一个好的解决方案,并被告知使用它的潜在风险。或者还有另一种方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

当你经常尝试自己时,从根本上远离物体会怎么样?

(x, y)打包为一个int中的两个short,或者将两个int打包为long。使用静态函数创建一个抽象类来进行操作。

public class Vector2 {
    private Vector2 {}

    public static short x(int v) {
        return (short)(v & 0xFFFF);
    }

    public static int add(int u, int v) {
        ...
    }

答案 1 :(得分:2)

潜在风险是并发修改,原因可能是:

1)您的doSomething方法被多个线程同时调用(在之前的情况下,每个调用创建了自己的本地Vector2实例)。解决方案:添加所需的同步。即使在单线程场景中,如果同时调用该方法,也可能会出现问题。

2)即使在单线程情况下,你(或其他程序员)也忘记了向量是在本地"本地"使用并从另一种方法修改它。解决方案:记录好。