Преимущества констант

Я понимаю, что одно из грандиозных предприятий о константах - то, что Вы не должны пройти и обновить код, где та константа используется повсеместно. Это является большим, но скажем, Вы явно не объявляете это как константу. Какое преимущество (преимущества) существуют (s) для взятия переменной, которая ПРОИСХОДИТ с на самом деле не быть измененной и сделать это константой, это будет экономить на обработке и/или размере кода... и т.д.?

В основном у меня есть программа, что в компиляторе говорится, что конкретная переменная не заменяется и таким образом может быть объявлена константой, я просто хотел знать, каково преимущество для добавления постоянного спецификатора к нему будет, если это не будет иметь никакого значения, затем вносящего то изменение, не добавляет никакое значение, и таким образом никакой смысл напрасно тратить время (этот тот же сценарий происходит в более затем одном месте), возвращение и "фиксация" всех этих переменных.

14
задан Daniel Grillo 31 March 2011 в 11:17
поделиться

14 ответов

Если вы объявите переменную константой, то оптимизатор часто может устранить ее с помощью "складывания констант" и тем самым ускорить работу программы и сэкономить место. В качестве примера рассмотрим следующее:

var int a = 5;
const int b = 7;
...
c = process(a*b);

В итоге компилятор создаст инструкцию умножения a на 7, передаст ее в 'process' и сохранит результат в c. Однако в этом случае:

const int a = 5;
const int b = 7;
...
c = process(a*b);

Компилятор просто передаст 35 в process и даже не будет кодировать умножение. Кроме того, если компилятор знает, что process не имеет побочных эффектов (то есть является простым вычислением), то он даже не будет вызывать process. Он просто установит c как возвращаемое значение process(35), сэкономив вызов функции.

22
ответ дан 1 December 2019 в 05:51
поделиться

Как вы отметили, вы не можете получить никакой прямой выгоды от преобразования неизменяемых переменных в явные константы. Однако при анализе программы одна проверка, которая выполняется, - смотреть от точки объявления переменной до точки ссылки на переменную. Таким образом, метрики, такие как переменные, к которым осуществляется доступ перед объявлением или которые устанавливаются и сбрасываются перед ссылкой и т.д., могут указывать на возможные ошибки.

Явно объявляя константы как константы, компилятор и инструменты анализа знают, что вы не собираетесь сбрасывать переменную в любое время.

Это также верно и для других разработчиков, которые работают с вашим кодом. Они могут непреднамеренно установить переменную, а вы можете не знать об этом. Объявление констант позволит избежать подобных ошибок.

3
ответ дан 1 December 2019 в 05:51
поделиться

Возможно, компилятор может уменьшить размер кода .. например, в пакете System вы найдете (на машине x86 )

type Bit_Order is (High_Order_First, Low_Order_First);
Default_Bit_Order : constant Bit_Order := Low_Order_First;

, так что с учетом

case System.Default_Bit_Order is
   when System.High_Order_First =>
      --  Big-endian processing
   when System.Low_Order_First =>
      --  Little-endian processing
end case;

компилятор может полностью исключить «неправильную» ветвь, в то время как ваш код сохранит свою переносимость. С GNAT вам нужно использовать оптимизацию не по умолчанию, чтобы это произошло: -O2 Я думаю.

Обе ветви должны быть компилируемыми - это оптимизация, а не обработка #ifdef .

3
ответ дан 1 December 2019 в 05:51
поделиться

Во многом это зависит от того, насколько хорош ваш оптимизатор.

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

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

Кроме того, всякий раз, когда это возможно, ваш код должен обеспечивать соблюдение предположений, сделанных вами во время разработки. Если «переменная» никогда не должна изменяться, объявление ее как константы поможет гарантировать, что ни вы, ни другие разработчики, которые придут позже, не будут непреднамеренно изменять «константу».

7
ответ дан 1 December 2019 в 05:51
поделиться

Константы обычно хранятся в постоянной памяти, что предотвращает их изменение во время выполнения, и доступ к ним может быть быстрее или, по крайней мере, таким же быстрым, как доступ к ОЗУ.

1
ответ дан 1 December 2019 в 05:51
поделиться

Если вы объявите что-то как константу, а затем случайно попытаетесь изменить это значение в своем коде, компилятор сообщит вам о вашей ошибке. Эта форма проверки статического типа фактически является основной причиной использования констант.

21
ответ дан 1 December 2019 в 05:51
поделиться

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

4
ответ дан 1 December 2019 в 05:51
поделиться

Одно из преимуществ состоит в том, что если это действительно постоянное значение, вы не сможете его случайно изменить. Константа удерживает вас от того, чтобы потом напортачить. В качестве переменной любой может прийти и изменить ее позже при обновлении кода.

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


Пример из реальной жизни из моей юности:

У нас не было встроенного значения PI в системе, над которой я работал, поэтому кто-то создал ПЕРЕМЕННУЮ под названием PI и где-то по пути кто-то (я) изменил это значение до 3,14519 (или что-то там около) в процедуре, которую я написал ... не приближение пи 3,14159). Он был установлен в другом месте кода, и с этого момента все виды вычислений были отключены. Если бы этот PI был константой (позже, конечно, он был изменен), я бы не смог сделать эту ошибку ... по крайней мере, нелегко.

2
ответ дан 1 December 2019 в 05:51
поделиться

В дополнение к тому, что уже было сказано, объявление переменной константой дает оптимизатору больше свободы. Он может исключить чтение ее значений, исключить необходимость создания временной копии, исключить саму переменную (это особенно верно для числовых констант).

Еще один важный случай использования констант - константные объекты. Имея константный объект (или передавая ссылку на константный объект в функции), вы можете быть уверены, что ваш объект не будет изменен, и только методы (называемые const методами) этого объекта могут быть вызваны. Однако это справедливо для C++, я не уверен, что та же концепция справедлива и в Ada.

2
ответ дан 1 December 2019 в 05:51
поделиться

Другая возможность, в зависимости от языка, состоит в том, что компилятор может выполнять некоторые оптимизации в многопоточной среде, которые в противном случае были бы невозможны. Например, если вы скажете:

int b=x*f;
int c=y*f;

В многопоточной среде, если f - переменная, компилятору, возможно, придется сгенерировать перезагрузку f перед второй операцией. Если f - константа, и компилятор знает, что она все еще находится в регистре, перезагрузка не требуется.

2
ответ дан 1 December 2019 в 05:51
поделиться

Конечно, для таких языков, как C и Ada, компилятор поместит значение из константы непосредственно в инструкцию ассемблера, что означает отсутствие обмена регистрами или чтения из памяти будет необходимо сверх того, что требуется для запуска программы. Это означает две вещи: основная - это скорость (вероятно, не так заметно во многих приложениях, если они не встроены), а вторая - использование памяти (как конечного двоичного размера программы, так и ее объема памяти во время выполнения).

Это поведение будет зависеть от языка и компилятора, поскольку язык будет диктовать любые предположения, сделанные вами (программистом) и, следовательно, ограничения эффективности языка; и компилятор, потому что его поведение может измениться от обработки вашей константы, как любой другой переменной, до предварительной обработки вашего кода и максимальной оптимизации двоичной скорости и объема памяти.

Во-вторых, как было заявлено itsmatt и jball, это позволяет вам логически рассматривать элемент как постоянный элемент конфигурации, а не как «переменную»; особенно в языках программирования более высокого уровня и интерпретируемых языках.

2
ответ дан 1 December 2019 в 05:51
поделиться

Есть еще одно преимущество - размеры стека и сегментов данных.

Учтите:

function Recurser(i : Integer) return Integer is
  ia : array(0..9) of Integer
          := (1, 2, 3, 4, 5, 6, 7, 8, 9, 1000);
  r : Integer;
begin
   if i = 0 then return 0; end if;
   r := ia(i mod 10);
   return r + Recurser(i - 1);
end;

Каждый раз, когда функция выполняет рекурсию, вы создаете структуру из 320 байт в стеке. Но поскольку значение a не меняется, стек увеличивается, чтобы содержать постоянную переменную. Это может быть очень важно на встроенных платформах с небольшими стеками.

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

2
ответ дан 1 December 2019 в 05:51
поделиться

Это не совсем вопрос Ada.

Общие преимущества констант перед переменными:

  • Предотвращает ошибки кода из-за случайного изменения "константы".
  • Сообщает компилятору, что он может предположить, что значение не изменится при оптимизации.

Особые преимущества Ada:

  • Для числовых констант вам не нужно указывать тип (именованные числа). Если вы объявите его таким образом, его можно будет использовать в любом выражении для такого числа. Если вместо этого вы используете переменную, ее можно использовать только в выражениях точного типа этой переменной .

Пример:

Seconds_Per_Minute : constant := 60;
Secs_Per_Min       : Integer  := 60;

type Seconds_Offset is 0 .. Integer'last; --'

Min1, Secs1 : Integer;
Min2, Secs2 : Seconds_Offset;

...
--// Using the named number, both of these compile no problem.
Secs1 := Min1 * Seconds_Per_Minute;
Secs2 :=  Min2 * Seconds_Per_Minute;

--// The second line here gives an error, since Integer is a 
--// different type than Seconds_Offset.
Secs1 := Min1 * Secs_Per_Min;
Secs2 := Min2 * Secs_Per_Min;
2
ответ дан 1 December 2019 в 05:51
поделиться

Константы - это неизменяемые значения, которые известны во время компиляции и не меняются в течение всей жизни программы.

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

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

0
ответ дан 1 December 2019 в 05:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: