Более эффективно использовать if-return-return или if-else-return? - PullRequest
106 голосов
/ 08 февраля 2012

Предположим, у меня есть if оператор с return. С точки зрения эффективности, я должен использовать

if(A > B):
    return A+1
return A-1

или

if(A > B):
    return A+1
else:
    return A-1

Стоит ли отдавать предпочтение тому или иному при использовании скомпилированного языка (C) или скриптового (Python)?

Ответы [ 9 ]

143 голосов
/ 08 февраля 2012

Поскольку оператор return завершает выполнение текущей функции, две формы эквивалентны (хотя вторая, возможно, более читабельна, чем первая).

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

Обратите внимание, что Python поддерживает синтаксис, который позволяет вам использовать только один оператор return в вашем случае:

return A+1 if A > B else A-1
28 голосов
/ 31 января 2015

С Руководство по стилю Chromium :

Больше не использовать после возврата:

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2
5 голосов
/ 08 февраля 2012

Относительно стиля кодирования:

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

(Хотя лично я бы сказал, что есть несколько случаев, когда несколько операторов return имеют смысл: синтаксические анализаторы текста / протокола данных, функции с расширенной обработкой ошибок и т. Д.)

Консенсус всех этих отраслевых стандартов кодирования заключается в том, что выражение должно быть записано как:

int result;

if(A > B)
{
  result = A+1;
}
else
{
  result = A-1;
}
return result;

Относительно эффективности:

Приведенный выше пример и два примера в вопросе полностью эквивалентны с точки зрения эффективности. Во всех этих случаях машинный код должен сравнивать A> B, затем переходить к вычислениям A + 1 или A-1, а затем сохранять результат этого в регистре ЦП или в стеке.

РЕДАКТИРОВАТЬ:

Источники:

  • MISRA-C: правило 14.7 2004 года, которое, в свою очередь, цитирует ...:
  • МЭК 61508-3. Часть 3, таблица B.9.
  • МЭК 61508-7. C.2.9.
3 голосов
/ 08 февраля 2012

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

1 голос
/ 27 ноября 2018

Я лично избегаю блоков else, когда это возможно. См. Кампания Anti-If

Кроме того, они не взимают «дополнительные» за линию, вы знаете: p

«Простое лучше, чем сложное» & «Читаемость - король»

delta = 1 if (A > B) else -1
return A + delta
1 голос
/ 08 февраля 2012

Версия A проще, и поэтому я бы ее использовал.

И если вы включите все предупреждения компилятора в Java, вы получите предупреждение для второй версии, потому что она не требует лишних усилий и увеличивает сложность кода.

0 голосов
/ 05 марта 2019

Думайте об этом так:

if (a > b):
    output = a + 1

output = a - 1

return output

По сравнению с этим:

if (a > b):
    output = a + 1
else:
    output = a - 1

return output

Первый пример не работает, а второй работает нормально. Они имеют одинаковую производительность, поэтому я рекомендую использовать пример 2. На мой взгляд, их легче читать.

0 голосов
/ 01 февраля 2018

Я знаю, что вопрос помечен как python, но в нем упоминаются динамические языки, поэтому я должен упомянуть, что в ruby ​​оператор if на самом деле имеет тип возврата, поэтому вы можете сделать что-то вроде

def foo
  rv = if (A > B)
         A+1
       else
         A-1
       end
  return rv 
end

Или потому, что онтакже имеет неявный возврат просто

def foo 
  if (A>B)
    A+1
  else 
    A-1
  end
end

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

0 голосов
/ 16 февраля 2017

Это вопрос стиля (или предпочтения), поскольку переводчику все равно.Лично я бы постарался не делать последнее утверждение функции, которая возвращает значение на уровне отступа, отличном от базы функции.Остальное в примере 1 затеняет, хотя и немного, где конец функции.

По предпочтению я использую:

return A+1 if (A > B) else A-1

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

Для более сложных функций я предпочитаю разбивать функцию на несколько подфункций, чтобы избежать преждевременных возвратов, если это возможно.В противном случае я вернусь к использованию императивной переменной стиля под названием rval.Я стараюсь не использовать несколько операторов return, если только функция не тривиальна или оператор return до конца не является результатом ошибки.Возвращение преждевременно подчеркивает тот факт, что вы не можете продолжать.Для сложных функций, которые разветвляются на несколько подфункций, я стараюсь кодировать их как операторы case (например, на основе dict).

В некоторых плакатах упоминается скорость работы.Скорость выполнения для меня вторична, так как, если вам нужна скорость выполнения, Python - не лучший язык для использования.Я использую Python, так как для меня важна эффективность кодирования (т.е. написания кода без ошибок).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...