Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

Сэм

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

Ответ 4

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

Из K & R, 2nd edition, p. 36:

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

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

Ответ 10

Обычно int является правильным выбором для циклирования. Есть две причины, по которым это может быть не так:

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

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

Ответ 11

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

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 обычно обеспечивает лучший результат.

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