Лучше использовать целые числа в качестве переменных счетчика цикла?

Я не забываю читать где-нибудь, что лучше использовать целые числа в качестве переменных счетчика цикла, а не символа или короткий. Если да, почему? Это предоставляет какие-либо преимущества оптимизации?

11
задан Jay 11 February 2010 в 09:28
поделиться

11 ответов

Обычно компилятор делает int подходящим размером для помещения в один из регистров общего назначения вашего процессора. Обычно это приводит к быстрому доступу.

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

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

14
ответ дан 3 December 2019 в 01:38
поделиться

В 32-битной архитектуре операции с 4-байтовыми (int) переменными обычно выполняются быстрее. В основном это связано с размером регистров и выравниванием памяти. В 64-битной архитектуре int будет (должен) автоматически стать 64-битным целым числом.

8
ответ дан 3 December 2019 в 01:38
поделиться

Было бы еще лучше использовать тип size _ t для счетчиков циклов. Он будет масштабироваться до 64 бит.

-121--2889020-

В некоторых случаях проблемы переполнения с char s (или даже short s) приводят к образованию не завершающих петель.

-121--2889023-

Алексей * прав, обычно быстрее использовать тип той же ширины, что и архитектура (т.е. int32 для 32-разрядной системы)

Кроме того, если вы используете символ, т.е.

for(char i=0;i<max;++i)

, есть небольшая вероятность того, что вы (или коллега) вернется к коду через месяц и изменит максимум на что-то высокое, вызывая переполнение и раздражающую ошибку;)

Сэм

* и все остальные, кто ответил, пока я писал это!

4
ответ дан 3 December 2019 в 01:38
поделиться

Обычно можно ожидать, что тип int будет самым быстрым реализованным целочисленным типом на вашей платформе, и поэтому он должен быть выбором по умолчанию.

Из K&R, 2-е издание, с. 36:

int : целое число, обычно отражающее естественный размер целых чисел на хост-машине.

3
ответ дан 3 December 2019 в 01:38
поделиться

Вы когда-нибудь замечали, что стандарт C не совсем точен в отношении размера целых чисел? Этот факт приводит в замешательство разработчиков драйверов устройств и тех, кто работает над протоколами связи, поскольку они считают, что язык должен четко определять размер объектов.

C говорит, что int является естественным размером для архитектуры реализации. Это означает, что с ним будут обращаться не менее эффективно, чем с любым другим размером. Возьмем архитектуру x86: short (16-битное целое число), используемое в 32-битной программе, содержит инструкции, выполняющие дополнительную модификацию «переопределения размера». Таким образом, код имеет больше байтов, хотя обычно без потери производительности. Если только лишние байты не вызывают переполнение строки кэша ....

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

2
ответ дан 3 December 2019 в 01:38
поделиться

Это действительно зависит от платформы, для которой вы пишете код. Лучше всего использовать его в соответствии с вашей платформой. То есть, если вы пишете код для простого 8-битного микроконтроллера, возможно, использование uint8_t лучше, чем использование uint16_t.

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

Было бы даже лучше использовать тип size_t для счетчиков циклов. Он будет масштабироваться до 64 бит.

2
ответ дан 3 December 2019 в 01:38
поделиться

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

Учитывая это, по умолчанию используйте int или unsigned int, если у вас нет причин поступать иначе - но я говорю так, потому что вам реже придется беспокоиться о переполнении или обводке при использовании большего типа, а не потому, что это может быть быстрее (хотя может).

2
ответ дан 3 December 2019 в 01:38
поделиться

Обычно int - правильный выбор для цикла. Этого может не быть по двум причинам:

  1. Он может быть больше, чем необходимо. SDCC поддерживает некоторые 8-битные процессоры, такие как Z80, которые разрешают 8-битный доступ к регистрам, хотя sizeof (int) = 2. Если вам не нужно более 8 бит для переменной цикла, то использование символов с sizeof (char) = 1 позволяет оптимизатору втиснуть больше в пространство регистров, что приводит к более быстрому выполнению кода.
  2. Это могло быть слишком мало. Если целые числа являются 16-битными, то у вас вполне могут быть циклы, которые выполняются более этого числа раз.

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

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

Это действительно зависит от того, что делает ваш цикл. Возьмем, к примеру, этот цикл:

typedef struct _SomeData
{
  /* some data here */
} SomeData;

void SomeFunction (SomeData *array_of_data, int number_of_elements)
{
  int i;

  for (i = 0 ; i < number_of_elements ; ++i)
  {
     DoSomethingWithData (&array_of_data [i]);
  }
}

Некоторые компиляторы хорошо справляются с оптимизацией вышеупомянутого. Но некоторые компиляторы, особенно компиляторы для нишевых встроенных микропроцессоров, будут генерировать ужасно неэффективный код. Его можно переписать как:

void SomeFunction (SomeData *array_of_data, int number_of_elements)
{
  SomeData *current = array_of_data, *end = &array_of_data [number_of_elements];

  while (current < end)
  {
    DoSomethingWithData (current++);
  }
}

, который вообще не использует целые числа и с большей вероятностью будет генерировать хороший результат независимо от компилятора (современные компиляторы, вероятно, все равно оптимизируют целочисленную версию до чего-то подобного выше).

Таким образом, целые числа не всегда необходимы для циклов, и лучшая оптимизация - всегда не делать того, в чем нет необходимости. Если, однако, циклу явно требуется целое число, тогда тип int обычно обеспечивает лучший результат.

Конечно, вы всегда должны использовать профилировщик, чтобы быть уверенным в производительности кода и в том, имеет ли изменение типа какое-либо значение.

0
ответ дан 3 December 2019 в 01:38
поделиться

В некоторых случаях проблемы переполнения с char s (или даже short s) приводят к возникновению незавершенных циклов.

1
ответ дан 3 December 2019 в 01:38
поделиться
Другие вопросы по тегам:

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