Я задаюсь вопросом если этот код:
int main(){
int p;
for(int i = 0; i < 10; i++){
p = ...;
}
return 0
}
точно то же как то
int main(){
for(int i = 0; i < 10; i++){
int p = ...;
}
return 0
}
с точки зрения эффективности? Я имею в виду, p переменная будет воссоздана 10 раз во втором примере?
Это семантическая разница, которую код скрывает, потому что она не имеет значения для int , но имеет значение разница для человеческого читателя. Вы хотите вынести значение любого вычисления, которое вы выполняете в ...
, за пределы цикла? Вы этого не сделаете, поэтому вам следует написать код, отражающий ваше намерение.
Человек-читатель должен будет искать функцию и искать другие варианты использования p
, чтобы убедиться, что то, что вы сделали, было просто преждевременной «оптимизацией» и не преследовало более глубокой цели.
Предполагая, что это имеет значение для используемого вами типа, вы можете помочь читателю, прокомментировав свой код
/* p is only used inside the for-loop, to keep it from reallocating */
std::vector<int> p;
p.reserve(10);
for(int i = 0; i < 10; i++){
p.clear();
/* ... */
}
В этом случае все то же самое. Используйте наименьшую область видимости для наиболее читабельного кода.
Если int
был классом со значительным конструктором и деструктором, то первый вариант (объявление вне цикла) может дать значительную экономию - но внутри обычно все равно нужно воссоздавать состояние... так что часто это оказывается совсем не экономией.
Один случай, когда это может иметь значение, - контейнеры. Строка или вектор используют внутреннее хранилище, которое увеличивается в соответствии с размером хранимых данных. Возможно, вы не захотите перестраивать этот контейнер каждый раз в цикле, а просто очистите его содержимое, и он не будет нуждаться в таком количестве перераспределений внутри цикла. Это может (в некоторых случаях) привести к значительному повышению производительности.
Итог - напишите это четко, и если профилирование покажет, что это имеет значение, уберите это :)
.Они равны по эффективности - вы должны доверить компилятору избавиться от неизмеримо маленькой разницы. Второй - лучший дизайн.
Изменить: это не обязательно верно для пользовательских типов, особенно тех, которые имеют дело с памятью. Если бы вы писали цикл для любого T, я бы на всякий случай использовал первую форму. Но если вы знаете, что это встроенный тип, например int, pointer, char, float, bool и т. Д., Я бы выбрал второй.
Во втором примере p виден только внутри цикла for. дальше в коде его использовать нельзя. С точки зрения эффективности они равны.