У меня такой цикл:
for(i = 0; i < arrayLength; i++)
{
result[i / 8] = SETBIT(result[i / 8], ++(*bitIndex), array[i]);
*bitIndex %= 8;
}
Интересно, что лучше, с точки зрения производительности, если я использую вышеупомянутый стиль или этот стиль:
for(i = 0; i < arrayLength; i++)
{
result[i / 8] = SETBIT(result[i / 8], ++(*bitIndex), array[i]);
if(*bitIndex == 8) *bitIndex = 0;
}
Это в C, составленном с помощью GCC, объяснение также будет оценено.
благодаря
Честно говоря, между ними будет только часть второй разницы. Но я считаю, что первая была бы ТАКЖЕ лучше для простого стиля READING. Тем не менее, этот вопрос ссылается на производительность, в которой я все еще думаю, что у первого будет край EVER SO SLIGHT для того, что компилятор читает/вычисляет меньше информации.
Нет смысла говорить об оптимизации...
В вашем случае для большинства систем разница между этими двумя примерами не будет. На чем вы должны сосредоточиться, это написать читаемый код вместо того, чтобы делать обратное. Подумайте о переписывании своей программы в нечто вроде этого:
for(i = 0; i < arrayLength; i++)
{
(*bitIndex)++;
SETBIT(&result[i / 8], *bitIndex, array[i]);
*bitIndex %= 8;
}
Вероятно, это даст тот же бинарный исполняемый файл, что и у вас, + - несколько тиков процессора.
Вы не говорите, почему bitIndex
- это указатель. Но, предполагая, что bitIndex
является параметром функции, содержащей данный цикл, я бы вытащил *bitIndex
материал из цикла, так что:
unsigned bi = *bitIndex ;
for(i = 0 ; i < arrayLength ; i++)
{
result[i / 8] = SETBIT(&result[i / 8], ++bi, array[i]) ;
bi %= 8 ;
} ;
*bitIndex = bi ;
[Я предполагаю, что ++bi
правильный, и что SETBIT()
требует 1..8, где bi
равно 0..7.]
Как отмечалось в других местах, компилятор имеет % 8
на завтрак и заменяет его на & 0x7
(для неподписанных, но не для подписанных). С помощью gcc -O2 выше выведен цикл из 48 байтов кода (15 команд). Скрипт с *bitIndex
в цикле составлял 50 байтов кода (16 команд), включая чтение и две записи *bitIndex
.
Насколько реальна разница в том, что кто-то догадывается... может быть, что чтение и запись памяти полностью подчиняются остальной части цикла.
Если bitIndex
является указателем на локальную переменную, тогда компилятор будет вытаскивать значение в регистр на протяжении всего цикла, поэтому он считает, что это стоит того!