Если вы точно знаете, сколько места нужно выделить и вашей главной заботой является производительность по отношению к управлению памятью и ваш код не должен быть Реентрантная, то вам нужно будет выделить объектов с статической продолжительностью хранения либо путем объявления их в области файлов, либо с помощью спецификатора класса хранения static
.
int data[SOME_NUMBER];
void foo(/* some list of parameters here */)
{
static int some_more_data[SOME_OTHER_NUMBER];
...
}
Оба data
и some_more_data
существуют в течение всего срока программы, но some_more_data
видна только в пределах foo
функций .
На практике элементы со статическим временем хранения имеют пространство, выделенное для них в самом двоичном изображении, так что память доступна, как только загружается программа. У этого может быть есть преимущество по сравнению с местностью; если данные и код находятся на одной странице, нет необходимости менять их. Конечно, это зависит от кода.
Очевидным недостатком является то, что ваш исполняемый файл будет иметь большую площадь. Еще один недостаток заключается в том, что ваш код не re-entrant; каждый вызов foo
работает над тем же блоком памяти, когда он читает или записывает some_more_data
. В зависимости от того, что делает ваш код, это может быть или не быть большим делом.
Если ваш код должен быть повторно включен, то вы не можете использовать объекты со статическим временем хранения. Если блок данных относительно невелик, используйте объекты с автоматическим временем хранения (т. Е. Регулярные локальные переменные).
void foo(/* some list of parameters here */)
{
int some_more_data[SOME_SMALLISH_NUMBER];
...
}
В этом случае some_more_data
существует только в течение времени жизни функции foo
; каждый раз, когда вы вызываете foo
, он автоматически назначает объект some_more_data
. Независимо от накладных расходов при отмене памяти это часть накладных расходов на вызов функции в первую очередь (по крайней мере, в моем опыте). Указатель стека по-прежнему настраивается независимо от того, используете ли вы локальные переменные или нет, поэтому использование локальных переменных не замедлит работу. Основная проблема заключается в том, что доступная память для автоматических объектов относительно невелика; для объектов выше определенного размера этот подход просто не сработает.
Если ваш код должен быть повторно абитуриент и вам нужно выделить большие блоки памяти, вы застряли в значительной степени с динамическим управлением памятью (malloc/calloc/realloc
и free
). В зависимости от того, как вы разрабатываете свой код, вы можете свести к минимуму некоторые проблемы с производительностью.
1. Правила визуализации применяются во время перевода с исходного на машинный код; они не применяются во время выполнения.
Это две совершенно разные «затраты». Статическое распределение является «бесплатным» с точки зрения времени выполнения, а память потребляет, если не используется с умом.Динамика оптимальна с точки зрения использования памяти (опять же, если использовать ее разумно), но требует затрат времени на процессор. –
Статическое распределение также имеет гораздо меньший размер, чем динамическое распределение. –
Это действительно не имеет значения. Память должна быть распределена в любом случае, дело в том, делает ли она компоновщик/загрузчик ОС или ваша программа. Если он * может * быть выполнен с помощью загрузчика, то по определению это стоимость за пределами цикла и совершенно неактуальна. –