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

Я делаю простую игру, и у нее есть один экземпляр класса с именем 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.