2015-03-03 3 views
1

Я не уверен, должен ли я спросить это здесь или в какой-то другой сайт StackExchange, но я буду продолжать ... Пожалуйста мигрировать, если он не подходит здесь)Предложения по улучшению читаемости этого кода

I я просматриваю код. Требование - вызвать функцию n количество раз с аргументом в диапазоне от 0 до n. Но если n больше 7, вызовите функцию только 7 раз.

Мой коллега реализовали его следующим образом:

void ExecuteFunctions(U8 count) 
{ 
    if(count > 0) oprA(0); 
    if(count > 1) oprA(1); 
    if(count > 2) oprA(2); 
    if(count > 3) oprA(3); 
    if(count > 4) oprA(4); 
    if(count > 5) oprA(5); 
    if(count > 6) oprA(6); 
    if(count > 7) oprA(7); 
} 

Я изменил его:

void ExecuteFunctions(U8 count) 
{ 
    for(U8 loopcnt = 0; loopcnt < count; loopcnt++) 
    { 
     oprA(loopcnt); 

     if(loopcnt == 7) 
     { 
      // We don't want to execute this function more number of times if it is already executed 7 times 
      break; 
     } 
    } 
} 

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

+1

Пусть компилятор оптимизировать его. Вероятно, он развернет цикл для вас. –

+0

@AustinMullins Хорошая идея, но оптимизация отключена. И вы можете сказать, теперь это стало для меня загадкой программирования! – Swanand

+1

Оптимизация для удобочитаемости или производительности? –

ответ

2

MIN макрос полезен и часто определяется

#define MIN(a,b)  (((a) > (b)) ? (b) : (a)) 
#define MAX_STEP 7 

void ExecuteFunctions(U8 count) 
{ 
    int loopcnt = 0; 
    count = MIN(count, MAX_STEP); 

    while(loopcnt++ < count) { 
     oprA(loopcnt); 
    } 
} 
+0

Вы должны также упомянуть о подводных ловушках 'MIN' macro. [Эта ссылка] (http://stackoverflow.com/a/3437484/3866447) также будет полезна здесь. –

+0

'while (loopcnt ++ chqrlie

2

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

void ExecuteFunctions(U8 count) 
{ 
    for(U8 loopcnt = 0; loopcnt < count && loopcnt < 8; loopcnt++) 
    { 
     oprA(loopcnt); 
    } 
} 

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

+1

Ницца 'for' loop. Примечание: 'swtich()' вызывает 'oprA()' в обратном порядке. – chux

+0

Правильно, вот почему я сказал: «Если заказ не имеет значения». –

+0

Почему да, вы сделали - еще один пример быстрого чтения и кода, говорящего громче, чем документация. – chux

1

Я хотел бы написать ее как

void ExecuteFunctions(unsigned count) { 
    // Could use min() too if available. 
    unsigned iters = count < 7 ? count : 7; 

    for (unsigned i = 0; i < iters; ++i) 
     oprA(i); 
} 

Размер кода, сформированного для этой функции составляет ~ 36 байт на x86_64 с GCC 4.9 и -O3. Размер исходной версии - 141 байт (GCC, похоже, не очень умный).

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

Update:

Следующая версия (измененная крошечную от ответа Остина - извините за кражу его :)) дает 32 байта от пути. Думаю, я предпочитаю это.

void ExecuteFunctions(unsigned count) { 
    for (unsigned i = 0; i < count && i < 8; ++i) 
     oprA(i); 
} 
+0

Нет такой вещи, как кража на SO. В конечном итоге получится лучший ответ. Не нужно упоминать меня в твоем. –

0
void ExecuteFunctions(U8 count) 
{ 
    for(U8 loopcnt = 0; loopcnt < (count & 7); loopcnt++) 
    { 
     oprA(loopcnt); 
    } 
} 
+0

Это вызовет это нулевое время для 'count == 8'. Может быть какой-то подобный трюк, хотя ... – Ulfalizer

+0

Очень хороший улов. Спасибо. – EvilTeach

0

Если вы действительно как switch заявления, попробовать это и посмотреть, если он выживает обзор кода:

void ExecuteFunctions(U8 count) { 
    int i = 0; 
    switch (count) { 
     default: oprA(i++); 
     case 6: oprA(i++); 
     case 5: oprA(i++); 
     case 4: oprA(i++); 
     case 3: oprA(i++); 
     case 2: oprA(i++); 
     case 1: oprA(i++); 
     case 0: oprA(i); 
    } 
} 
Смежные вопросы