2011-01-08 3 views
2

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

Иногда мы сталкиваемся с ситуациями, как это в программах:

if(bob == 42) 
{ 
    /* ... */ 
    return; 
} 
else 
{ 
    /* ... */  
} 

else блока здесь не является строго необходимым, как вы, вероятно, можете видеть. То же самое происходит и с другими структурами управления потоком программ; некоторые «обычные» конструкции становятся излишними из-за особых условий. Возникает вопрос: есть ли причина писать эти избыточные блоки кода? Ясность? Может ли это помочь компилятору с оптимизацией, если ситуация была достаточно сложной?

ответ

1

Я имею в виду то, что вы написали как «самодокументирующий код». Используя блок else, вы упрощаете людям видеть, что если bob не равен 42, загорится 2-й блок кода.

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

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

Что касается запуска кода, выполните некоторые тесты с некоторым временным кодом, чтобы узнать, что работает лучше.

+0

+1, хороший момент с профилированием. Наверное, здесь нет общего правила, когда дело доходит до производительности. Когда дело доходит до читаемости, это, конечно, субъективная вещь. Я полагаю, что некоторые из них найдут много ненужных вложенных блоков 'else', которые трудно читать. – Oystein

+0

Профилирование? В самом деле? Это похоже на большую работу за то, что любой современный компилятор, вероятно, относится к тому же. Кажется маловероятным, что профилировщик даже продемонстрировал бы разницу, даже если компилятор создавал другой код. (Если кто-то действительно интересуется, я бы сказал, глядя на сборщика, который создается.) – davep

+0

@ davep: Конечно, никто не заботится о примере bob, но я мог представить себе более сложные сценарии, где было бы полезно проанализировать различия (не так много в C, может быть, но определенно в C++). – Oystein

1

Для себя, я часто пишу

if(bob == 42) 
{ 
    /* ... */ 
    return; 
} 
/* else */ 

/* ... */ 

хотя я мог бы быть то здесь отсутствует.

РЕДАКТИРОВАТЬ: Я также только что понял вопрос о сфере применения здесь. По крайней мере, на C++ (не в старом C, не уверенном в C99?) Блок else имел бы свою «собственную» разную область, о которой стоит обратить внимание.

0

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

/* Is bob 42 ? */ 
if(bob == 42) 
{ 
    /* Bob is 42, return from function */ 

    return; 
} 
else 
{ 
    /* Bob is not 42, do nothing */ 
} 

компилятор должны оптимизировать из пустого еще пункта.

+3

Если это иллюстрирует те комментарии, которые кто-то может написать, я укажу, что замена 42 на какой-то другой номер требует изменения 4 строк кода вместо одного. Или это эффективный способ создать 2-3 неправильных комментария. (Я соглашусь, что компилятор не будет заботиться о «избыточном».) – davep

+0

@ davep: +1, Nice catch – Oystein

+0

True. Комментарии достойны написания, когда они говорят что-то большее, чем говорит код, приведенный ниже. И если код ничего не говорит, часто лучше сделать код более самодокументированным, чем документировать его. – Kos

0

Я предпочел бы только одна линия (если это равносильно тому, что вы имели в виду)

if (bob == 42) return; 

Это как раз говорит, что она делает, и не нуждается в дополнительных комментария. В противоположность этому, вставляя в else блок и комментарии и прочее, запутывает код и отвлекает от происходящего, в частности от важного другого кода, который может следовать.

Повторяя одно и то же сообщение с небольшими изменениями в комментариях, читатель читает код для глупого.

Если бы это было не то, что вы имели в виду с кодом snipset, если есть на самом деле что-то делать в обоих случаях, я бы предпочел

if (bob == 42) { 
    /* do something if bob is the chosen one */ 
} else { 
    /* for all others apply the standard treatment */ 
} 
return; 

Это не скрывает ваш оператор возврата глубоко внутри блока ,

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

+0

Нет, не делайте этого (единственная вещь)! Это затрудняет переход при отладке. – davep

+0

@ davep: Вау, какой аргумент. Просто положить его на две строки с отступом «возврат», который бы соответствовал вашим потребностям? Итак, чтобы оценка выражения и оператора 'return' получили разные номера строк? В противном случае я должен сказать, что, надеюсь, код читается чаще, чем есть, но с помощью отладчика. Снова я бы сказал примерно то же самое, что и в конце моего ответа: если в таком случае вы не можете отличить, где вы находитесь с вашим отладчиком, то в вашем дизайне, во-первых, что-то не так. –

+0

Ваш комментарий немного трудно следовать. Да, две отдельные строки. Я не сказал, что один «не может отличить» (вы создаете соломенного человека). Сделать код проще, без каких-либо преимуществ. Таким образом, у вас есть проблема «спрятать ваш оператор возврата в глубине блока», но у вас нет проблемы, скрывающейся в конце строки? Если ваше условное значение действительно длинное, тогда * критический * возврат будет неясным, если он будет справа (возможно, даже скрыт от экрана). – davep

 Смежные вопросы

  • Нет связанных вопросов^_^