简体   繁体   English

在每个方法调用上传递引用或在实例创建时传递一次

[英]Passing reference on every method call or once on instance creation

I'm making a simple game, and it has a single instance of a class named Game that deals with all the logic of the game. 我正在做一个简单的游戏,它有一个名为Game的类的单个实例,它处理Game所有逻辑。

Many of the classes in the project have a method called tick() which is called from within the Game instance 60 times per second and deals with updating information. 项目中的许多类都有一个名为tick()的方法,该方法在Game实例中每秒调用60次并处理更新信息。 Such instances are stored in list(s) in the Game class. 这些实例存储在Game类的列表中。

This method requires access to the Game class and currently looks like this: 此方法需要访问Game类,目前看起来像这样:

MyClass {
    public void tick(Game game) {
        ...
    }
}

My question is - would it be better to do as I am doing now and pass a reference hundreds and thousands of times per second to all the instances that require it or simply pass a single reference to these instances on creation and have the classes look like so: 我的问题是 - 现在做的更好 ,并且每秒将引用数百次传递给所有需要它的实例,或者只是在创建时将这些实例传递给这些实例并使类看起来像所以:

MyClass {
    private Game game;
    public MyClass(Game game) { this.game = game }
    public void tick() { ... }
}

Basically, how taxing it is to pass this reference so many times every second? 基本上,每秒多次传递这个引用是多么的繁琐?

Thanks in advance. 提前致谢。

Edit: Perhaps another option is to mark all the required members of the Game class as static and calling them as such without a reference at all?.. 编辑:也许另一种选择是将Game类的所有必需成员标记为静态,并在没有引用的情况下将它们调用为这样?

It's not that taxing. 这不是那么费力。 You should make the decision based on design, not speed. 你应该根据设计做出决定,而不是速度。

Does the Game passed in ever change? 游戏是否通过了变化? If not, it's probably best to pass it in during the constructor, and make the field final for clarity. 如果没有,最好在构造函数中传递它,并使字段最终为清晰。

But, are there many many Games? 但是,有很多游戏吗? If so, it probably makes sense to pass it in the method so you don't have to construct tons and tons of MyClass - you can make due (perhaps) with only one. 如果是这样的话,将它传递给方法可能是有意义的,这样你就不必构建大量的MyClass - 你可以只用一个来做(也许)。

Please profile before you find this to be a bottleneck. 在您发现这是一个瓶颈之前请先了解一下。 I don't think this really matters in your program. 我不认为这对你的计划很重要。

But the cons are that the memory occupied by MyClass will increase if it has Game as a member. 但缺点是,如果将Game作为成员,MyClass占用的内存将会增加。 If you are creating a lot of MyClass your program will use more memory. 如果要创建大量MyClass,程序将使用更多内存。

You'd probably have to profile this to get a definitive answer. 您可能需要对此进行分析以获得明确的答案。 You're balancing the cost of pushing an argument onto the stack and accessing the argument inside the function versus accessing an instance field from within the function. 您正在平衡将参数推入堆栈并访问函数内部的参数与从函数内访问实例字段的成本。 My guess is that this will be close to a wash. 我的猜测是,这将接近洗涤。

If game changes identity during execution, then there's a big win for passing it as an argument every time. 如果game在执行过程game改变了身份,那么每次传递它作为参数都是一个巨大的胜利。 It doesn't sound like that applies in your case, however. 但是,听起来并不适用于您的情况。

I was sure that there is no (or minimal) taxing but decided to verify this fact. 我确信没有(或极少)征税但决定验证这一事实。 Here is my code: 这是我的代码:

public class Test {
    public static void main(String[] args) {
        Test t = new Test();

        long before = System.currentTimeMillis();
        for (int i = 0;  i < 10000000;  i++) {
            t.foo();
        }
        long after = System.currentTimeMillis();
        System.out.println("no args: " + (after - before));


        before = System.currentTimeMillis();
        for (int i = 0;  i < 10000000;  i++) {
            t.foo(t);
        }
        after = System.currentTimeMillis();
        System.out.println("with args: " + (after - before));

    }

    private int foo() {
        return hashCode() * 2;
    }

    private int foo(Object arg) {
        return arg.hashCode() * 2;
    }
}

I ran it several times and did not see any significant difference between foo() and foo(Object) calls performance. 我运行了几次,并没有看到foo()foo(Object)调用性能之间有任何显着差异。 Moreover sometimes arg-full version runs faster than arg-less: 此外,有时arg-full版本的运行速度比arg-less快:

c:\temp>java -cp . Test
no args: 17
with args: 20

c:\temp>java -cp . Test
no args: 17
with args: 18

c:\temp>java -cp . Test
no args: 16
with args: 19

c:\temp>java -cp . Test
no args: 17
with args: 18

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM