Я помню, где-то читал, что лучше использовать целые числа как переменные счетчика циклов, а не char или короткие. Если да, то почему? Предоставляет ли он какие-либо преимущества оптимизации?
Лучше ли использовать целые числа в качестве переменных счетчика циклов?
Ответ 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 обычно обеспечивает лучший результат.
Конечно, вы всегда должны использовать профилировщик, чтобы быть уверенным в производительности кода и независимо от того, имеет ли значение изменение тип.