Имеет ли static значение для локальной переменной const? - PullRequest
0 голосов
/ 01 марта 2019

Представьте себе следующее объявление:

void foo(){
    const std::array<int, 80000> arr = {/* a lot of different values*/};
    //do stuff
}

И второе:

void foo(){
    static const std::array<int, 80000> arr = {/* a lot of different values*/};
    //do stuff
}

Каковы возможные различия в производительности между этими двумя, если таковые имеются?И есть ли опасность, связанная с каким-либо из этих решений?

Ответы [ 4 ]

0 голосов
/ 01 марта 2019

Забудьте массив на мгновение.Это запутывает две отдельные проблемы.У вас есть ответы, которые касаются проблемы времени жизни и хранения .Я рассмотрю проблему initialization .

void f() {
    static const int x = get_x();
    // do something with x
}

void g() {
    const int x = get_x();
    // do something with x
}

Разница между этими двумя заключается в том, что первый вызов будет вызывать get_x() только при первом вызове f();x сохраняет это значение до конца программы.Второй будет вызывать get_x() каждый раз, когда вызывается g().

Это имеет значение, если get_x() возвращает различные значения при последующих вызовах:

int current_x = 0;
int get_x() { return current_x++; }
0 голосов
/ 01 марта 2019

Каковы возможные различия в производительности между этими двумя, если таковые имеются? И есть ли какая-либо опасность, связанная с любым из этих решений?

Разница в точности зависит от того, как вы используете foo().

1-й случай: (низкая вероятность): Ваша реализация такова, что вы вызовете foo() только один раз, возможно, вы создали отдельную функцию для разделения логики кода, как это практикуется.Хорошо в этом случае объявление как статическое очень плохо, потому что статическая переменная или объект остается в памяти, пока программы не заканчиваются.Так что просто представьте, что ваша переменная занимает ненужную память.

2-й случай: (высокая вероятность): ваша реализация такова, что вы будете вызывать foo() снова и снова.Тогда нестатический объект будет выделяться и снова выделяться снова и снова. Это займет огромное количество тактов процессора, что нежелательно. В этом случае используйте статический.

0 голосов
/ 01 марта 2019

В этом конкретном контексте следует рассмотреть один вопрос, касающийся использования static для переменной с инициализацией:

Из стандарта C ++ 17:

6.7.1 Статическое хранилищеduration [basic.stc.static]
...
2 Если переменная со статической продолжительностью хранения имеет инициализацию или деструктор со сторонойэффекты, , он не должен быть удален, даже если кажется, что он не используется , за исключением того, что объект класса или его копирование / перемещение могут быть удалены, как указано в 15.8.

0 голосов
/ 01 марта 2019

И есть ли какая-либо опасность, связанная с каким-либо из этих решений?

Нестатично опасно, поскольку массив огромен, а память, зарезервированная для автоматического хранения, ограничена.В зависимости от системы и конфигурации этот массив может использовать около 30% пространства, доступного для автоматического хранения.Таким образом, это значительно увеличивает вероятность переполнения стека.

Хотя оптимизатор может определенно избежать выделения памяти в стеке, есть веские причины, по которым вы бы хотели, чтобы ваша неоптимизированная отладочная сборка также не вылетала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...