2016-03-29 6 views
0
class MyClass { 
    private: 
     unsigned int currentTimeMS; 
    public: 
     void update() { 
      currentTimeMS = getTimeMS(); 
      // ... 
     } 
}; 

class MyClass { 
    public: 
     void update() { 
      unsigned int currentTimeMS = getTimeMS(); 
      // ... 
     } 
}; 

update() вызывает основной цикл игры, поэтому во втором случае мы получаем много операций выделения (unsigned int currentTimeMS). В первом случае мы получаем только одно выделение и используем эту выделенную переменную раньше. Какой из этих кодов лучше использовать и почему?Что лучше использовать и почему?

+1

Всё зависит от меня. Вам нужна переменная 'currentTimeMS' где-нибудь еще? Где-то, где вы не можете напрямую называть 'getTimeMS'? –

+1

В этом вопросе недостаточно кода или контента. Кроме того, ваше звание, серьезно? – juanchopanza

+0

в первом фрагменте, является 'getTimeMS();' предполагается быть 'getTimeMS;'? – user463035818

ответ

8

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

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

+2

Как вы можете это рекомендовать? Вы не знаете, что он делает с результатом. Возможно, его нужно будет использовать в другом месте. –

+1

@afrogonabike: Из его примера кода я пришел к выводу, что переменная используется только в методе 'update()'. В противном случае у него не было бы обоих вариантов. –

+0

да, я думаю, это правда. Неизвестно, находится ли в ОП отсутствует базовое понимание деклараций классов или вопрос идет глубже. OP? –

0

В первом примере вы сохраняете состояние этого объекта класса. Во втором - нет, поэтому текущее время будет потеряно, когда вызывается мгновенное обновление().

Это действительно зависит от вас, чтобы решить, какой из них вам нужен.

0

Первый случай определяет переменную-член во второй локальной переменной. Базовый класс. Личная переменная-член доступна для любой функции (метода) в этом классе. локальная переменная доступна только в функции, в которой она объявлена.

1

Это зависит от ваших потребностей. Если currentTimeMS необходимо только временно в update(), то обязательно объявите его там. (В вашем случае, # option2)

Но если это значение необходимо для экземпляра класса (т.е. используется каким-либо другим способом), то вы должны объявить его как поле (в вашем случае , # опция1).

0

Какой из этих кодов лучше использовать и почему?

В первую очередь цитируемый код является в лучшем случае крошечной микро-оптимизацией. Не беспокойтесь о таких вещах, если вам это не нужно.

Фактически, это, скорее всего, диссоптимизация. Иногда в стеке выделяются автоматические переменные. Распределение стека чрезвычайно быстрое (и даже иногда свободное). Не нужно беспокоиться. В других случаях компилятор может поместить небольшую автоматическую переменную, такую ​​как unsigned int, которая используется здесь в регистре. Нет никакого распределения.

Сравните это с тем, чтобы сделать переменную членом данных класса и исключительно с целью избежать этого распределения. Доступ к этой переменной включает в себя прохождение указателя this. Развертка указателя имеет стоимость, потенциально намного выше, чем при добавлении смещения к указателю. Разрыв может привести к промаху в кеше. Хуже того, это разыменование может быть выполнено каждый раз, когда на ссылку ссылается переменная.


При этом иногда лучше создавать элементы данных исключительно с целью избежать автоматических переменных в различных функциях-членах. Большие массивы, объявленные как локальные автоматические переменные, вполне могут привести к переполнению стека.Обратите внимание, однако, что создание double big_array[2000][2000], член данных MyClass, скорее всего, сделает невозможным, чтобы переменная типа MyClass была объявлена ​​как локальная автоматическая переменная в некоторой функции.

Стандартное решение проблем, создаваемых путем размещения больших массивов в стеке, заключается в том, чтобы вместо этого распределить их по куче. Это приводит к тому, что создание элемента данных для избежания локальной переменной может быть полезным. Хотя распределение стека чрезвычайно быстрое, распределение кучи (например, new) происходит довольно медленно. Функция-член, которая вызывается многократно, может выиграть, сделав автоматическую переменную std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) членом данных MyClass.

Обратите внимание, что ни одно из вышеизложенного не относится к образцу кода в вопросе. Обратите также внимание на то, что последнее беспокойство (создание переменной, распределенной по кучим, членом данных, чтобы избежать повторных распределений и освобождения) означает, что код должен пройти через указатель this для доступа к этой памяти. В узком коде мне иногда приходилось создавать локальную переменную автоматического указателя, такую ​​как double* local_pointer = this->some_pointer_member, чтобы избежать повторных обходов через this.

Смежные вопросы