2010-02-16 4 views
0

Каковы достоинства и недостатки следующих фрагментах два кода:Читаемость кода против лаконичности

return n==0 ? 0 : n==1 ? 1 : fib(n-1) + fib(n-2); 

и

if(n==0) 
    return 0; 
if(n==1) 
    return 1; 
return fib(n-1) + fib(n-2); 

для вычисления п-й буквы в последовательности Фибоначчи?

Какой из них вы бы пожелали и почему?

+7

Сообщество wiki? – falstro

+6

Я предпочитаю 'return round (pow (GOLDEN_RATIO, n)/sqrt (5));' – kennytm

+1

n-я буква? Это римская версия последовательности Фибоначчи? –

ответ

7

Первый - это дьявол и должен быть очищен огнем.

+1

И второй немного лучше. – Clifford

+0

Что не так с первым? –

+0

@ Yassir - не рассчитать число фибоначчи – mocj

1

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

я сделаю это что-то вроде этого (псевдо-код):

a = 0; 
b = 1; 
n.times { a, b = b, a + b; } 

В C вам придется использовать временную переменную, к сожалению, но принцип тот же.

+1

Ничего себе, как восхитительно по теме, но совсем не по теме. – Earlz

+0

Earlz: Лицемер? http://stackoverflow.com/questions/2274937/code-readability-vs-conciseness/2275002#2275002 –

+0

umm? Я не понимаю. – Earlz

1

Я предпочитаю второй по сравнению с первым, в основном для удобства чтения.

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

Лично я обнаружил, что множественные, цепные троичные операции трудно выполнить в разы.

Кроме того, я лично считаю, что «лаконичность» является плохой целью, в большинстве случаев. Современные IDE делают «более длинный» код намного более управляемым, чем раньше. Я не говорю, что вы хотите быть слишком многословным, но попытка быть кратким часто приводит к увеличению усилий по обслуживанию, по моему опыту.

6

я бы пользу:

return n <= 1 ? n : fib(n-1)+fib(n-2); 
+1

n должно быть неподписанным, так как fib (-1) не определено – Tom

+1

Действительно; ни одно из предложений Тома не имеет большого достоинства. – Clifford

+0

Том: Конечно. Но твоя еще хуже. Они не прекращались до тех пор, пока они не переполнили бы IntXX.MinValue и не вернулись к 0. Возможно даже переполнение стека до этого ... –

1

Если вы просите читаемость, я бы предпочел второй вариант, поскольку он не содержит (двойной!) Тройной оператор. Обычно вы пишете код, который другие люди также должны читать, а из второго фрагмента ясно, что делает функция. Однако в первом фрагменте нужно разрешить оба тройных оператора «в голове» и дополнительно подумать об ассоциативности (я думаю об этом автоматически, потому что в скобках отсутствует).

Но в любом случае, вы можете уменьшить два, если заявления в одном:

if(n <= 1) return n; 
return fib(n-1) + fib(n-2); 
0

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

return n==0 ? 0 : (n==1 ? 1 : fib(n-1) + fib(n+1)); 
+1

Я постараюсь сделать ваш ответ более удобным для чтения;) – Earlz

4

я предпочел бы писать:

if (n == 0) { 
    return 0; 
} 
else if (n == 1) { 
    return 1; 
} 
else { 
    return fib(n-1) + fib(n-2); 
} 

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

+1

Я согласен, в мое мнение, скобки никогда не должны быть опущены. – dassouki

+0

Согласен, не опускайте брекеты. (Хотя я предпочитаю открывать скобу на отдельной строке) –

+0

Не согласен, пожалуйста, оставьте брекеты. Добавление фигурных скобок в однострочных операциях if эквивалентно добавлению точек с запятой в конец каждой строки в Python. –

2

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

Программирование не отличается. Вы должны оценить

  • простоты
  • краткость
  • эффективность
  • практичности
  • артистической свободы выражения
  • временных ограничений

и найти сладкое пятно.

Ваша первая конструкция явно мощная и вызывающая, но определенно не простая для понимания.

0

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

text="my stuff_"+id==null ? "default" : id; 

к

text="my stuff_"; 
if(id==null){ 
    text+="default"; 
}else{ 
    text+=id; 
} 

Примечание, это также помогает с DRY, потому что теперь, если вам нужно изменить имя text, то вы только изменить его в одном месте, по сравнению до 3.

0

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

0

Я бы сказал, что даже больше, чем @Lauri:

if (n == 0) { 
    tmp = 0; 
} 
else if (n == 1) { 
    tmp = 1; 
} 
else { 
    tmp = fib(n-1) + fib(n-2); 
} 
return tmp; 

Хорошо иметь только одну точку выхода.

+0

Итак, вы предпочли бы использовать временную переменную, чем иметь 3 точки возврата все в конце функции и все в одном месте? – Earlz

+0

В чем проблема? Компилятор должен иметь возможность оптимизировать это без проблем, и он помогает записывать поддерживаемый и отлаживаемый код. – fortran

+0

Внедрение временной переменной строго для того, чтобы ограничить себя наличием только одной точки выхода, противоположной «поддерживаемому» кодированию. – mocj

1

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

if (n <= 1) 
    return n; 
else 
    return fib(n-1) + fib(n-2); 

Или, если вы не в нескольких возвращениях:

if (n > 1) 
    n = fib(n-1) + fib(n-2); 
return n; 
1

Я часто нахожу, что отступы можно сделать несколько-тройные оператор намного более читаемым:

return n == 0 ? 0 : 
     n == 1 ? 1 : 
       fib(n-1) + fib(n-2); 
0

Как общее правило, вы должны писать читаемый код, который означает, что код, который является наиболее читаемыми людьми, которые на самом деле читать его. Большую часть времени это означает «вы, через три недели». Когда вы пишете код, тогда возникает хороший вопрос: «смогу ли я снова и снова прочитать его в следующем месяце?».

Кроме того, первое выражение глючит (он использует fib(n+1) вместо fib(n-2)) и оба демонстрирует экспоненциальный взрыв, который делает последовательность Фибоначчей классический инструмент для обучения некоторых важных практических аспектов алгоритмики.

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