Редактировать: Я знаю, что объявление объекта перед телом цикла более эффективно, так как оно вызывает конструктор и деструктор для вызова функции, а не один раз для итерации цикла. Допустим, что из-за этого рассуждения объекты типа A более эффективны вне тела цикла.
Мне интересно, если следующее
void foo()
{
static A var; //A is a class with a constructor
... //stuff done with var
}
более эффективен, чем
void foo()
{
A var; //A is a class with a constructor
... //stuff done with var
}
поскольку первый вызовет конструктор и деструктор A один раз, а не последний, который делает это за вызов foo. Я задаю этот вопрос в основном по всем местным объектам.
Прежде всего, это семантически отличается. Вы сравниваете две разные вещи. Если вас не волнует семантическая разница, один из них может быть быстрее другого. Если строительство A
не делает много, например, просто инициализирует int
вполне возможно, что вторая версия быстрее, например, потому что компилятор должен знать, инициализирован ли он var
во время выполнения и в C ++ 11 инициализация является поточно-ориентированной. Если строительство A
В некоторой степени, вероятно, первая версия работает быстрее.
Единственный способ выяснить для любого приложения является измерение.
Практическое правило. Кодируйте, что вы имеете в виду (локальный объект или его необходимо разделять при каждом вызове?), И позвольте компилятору беспокоиться об оптимизации.
Я делаю исключение для констант нетривиальных типов. Например, «static const std :: string» лучше, чем «const std :: string», потому что каждый раз сохраняет динамическое распределение. Но если объект не содержит динамических распределений и его размер не равен десяткам байтов, сделайте его локальной переменной.
Нет необходимости делать основные типы (такие как const int
или же const char *const
) статично по соображениям эффективности, хотя это не повредит.
Поскольку статический объект совместно используется потоками, компилятору может потребоваться проверять, не обновлялся ли он другим потоком каждый раз, когда ему необходимо его использовать, что не может быть в случае локальной переменной. Так что не думайте, что static будет самым быстрым. (Как это работает, зависит от реализации вашего компилятора)
Конечно, вам также необходимо понять, как статическое или нет может изменить поведение вашей программы. Моя информация выше предполагает, что выбор не будет.
Сначала сделайте это правильно, затем сделайте это быстро. Версия со статической переменной переносит значение из предыдущего вызова; если вам не нужно сохранять информацию в нескольких вызовах, хороший дизайн требует установки переменной в известное состояние, что делает конструктор. Если вы не используете конструктор, то есть вы делаете переменную статической, то вам нужно сделать что-то еще, чтобы перевести переменную в известное состояние; то есть вы в конечном итоге вызываете функцию, которая делает то, что сделал бы конструктор, но у вас более неясный синтаксис.
Вот несколько упрощенный пример:
void f(int j) {
static int i = 0;
i = 0; // reset, because previous call left i with some spurious value
while (i < j)
std::cout << i << '\n';
}
Помимо этого, совместное использование этой переменной между вызовами означает, что в многопоточной программе вам придется синхронизировать все вызовы этой функции, создавая узкое место, которое почти наверняка компенсирует любой выигрыш в производительности, если не создавать объект каждый раз, когда он используется.