Передача справки по каждому вызову метода или один раз при создании экземпляра

Я делаю простую игру, и у нее есть один экземпляр класса с именем Game, который имеет дело со всей логикой игры.

Многие из классов проекта имеют метод tick(), который вызывается из экземпляра Game 60 раз в секунду и обрабатывает информацию об обновлении. Такие экземпляры хранятся в списке (-ях) в классе Game.

Этот метод требует доступа к классу Game и в настоящее время выглядит следующим образом:

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

Мой вопрос: было бы лучше делать то, что я делаю сейчас, и передавать сотни и тысячи раз в секунду всем экземплярам, ​​которые этого требуют, или просто передать одну ссылку на эти экземпляры при создании и иметь классы выглядят так:

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

В принципе, как облагать налогом эту ссылку столько раз каждую секунду?

Спасибо заранее.

Edit: Возможно, еще один вариант - отметить все необходимые члены класса Game как статические и вызывать их как таковые без ссылки вообще?..

4 ответа

Вам, вероятно, придется профилировать это, чтобы получить окончательный ответ. Вы балансируете стоимость нажатия аргумента в стек и доступа к аргументу внутри функции по сравнению с доступом к полю экземпляра внутри функции. Я предполагаю, что это будет близко к стирке.

Если game изменяет идентификацию во время выполнения, тогда есть большая победа для передачи ее в качестве аргумента каждый раз. Однако это звучит не так, как в вашем случае.


Это не то, что налоги. Вы должны принять решение на основе дизайна, а не скорости.

Играет ли игра в когда-либо? Если нет, лучше всего передать его во время конструктора и сделать поле окончательным для ясности.

Но много ли игр? Если это так, вероятно, имеет смысл передать его в методе, поэтому вам не нужно создавать тонны и тонны MyClass - вы можете сделать это (возможно) только с одним.


Просьба профайл, прежде чем вы обнаружите, что это узкое место. Я не думаю, что это действительно важно в вашей программе.

Но недостатком является то, что память, занятая MyClass, будет увеличиваться, если в ней есть Игра. Если вы создаете много MyClass, ваша программа будет использовать больше памяти.


Я был уверен, что нет (или минимального) налога, но решил проверить этот факт. Вот мой код:

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

Я запускал его несколько раз и не видел существенной разницы между производительностью вызовов foo() и foo(Object). Более того, иногда версия 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

licensed under cc by-sa 3.0 with attribution.