使用if-return-return或if-else-return更有效吗?

问题:使用if-return-return或if-else-return更有效吗?

假设我有一个if带有的语句return。从效率的角度来看,我应该使用

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

要么

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

使用编译语言(C)或脚本化语言(Python)时,我应该选择一种还是另一种?

Suppose I have an if statement with a return. From the efficiency perspective, should I use

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

or

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

Should I prefer one or another when using a compiled language (C) or a scripted one (Python)?


回答 0

由于该return语句终止了当前函数的执行,因此两种形式是等效的(尽管第二种形式比第一种更具可读性)。

两种形式的效率都相当,如果if条件为假,则基础机器代码必须执行跳转。

请注意,Python支持一种语法,该语法仅允许您使用一种return情况:

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

Since the return statement terminates the execution of the current function, the two forms are equivalent (although the second one is arguably more readable than the first).

The efficiency of both forms is comparable, the underlying machine code has to perform a jump if the if condition is false anyway.

Note that Python supports a syntax that allows you to use only one return statement in your case:

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

回答 1

根据Chromium的风格指南:

返回后请勿使用其他:

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2

From Chromium’s style guide:

Don’t use else after return:

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2

回答 2

关于编码风格:

无论哪种语言,大多数编码标准都禁止从单个函数中使用多个返回语句,这是一种不好的做法。

(尽管我个人会说在某些情况下多个返回语句确实有意义:文本/数据协议解析器,具有大量错误处理的功能等)

所有这些行业编码标准的共识是,该表达式应写为:

int result;

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

关于效率:

上面的示例和问题中的两个示例在效率方面都完全等效。在所有这些情况下,机器码都必须比较A> B,然后跳转到A + 1或A-1计算,然后将结果存储在CPU寄存器或堆栈中。

编辑:

资料来源:

  • MISRA-C:2004规则14.7,依次引用…:
  • IEC 61508-3。第3部分,表B.9。
  • IEC 61508-7。C.2.9。

Regarding coding style:

Most coding standards no matter language ban multiple return statements from a single function as bad practice.

(Although personally I would say there are several cases where multiple return statements do make sense: text/data protocol parsers, functions with extensive error handling etc)

The consensus from all those industry coding standards is that the expression should be written as:

int result;

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

Regarding efficiency:

The above example and the two examples in the question are all completely equivalent in terms of efficiency. The machine code in all these cases have to compare A > B, then branch to either the A+1 or the A-1 calculation, then store the result of that in a CPU register or on the stack.

EDIT :

Sources:

  • MISRA-C:2004 rule 14.7, which in turn cites…:
  • IEC 61508-3. Part 3, table B.9.
  • IEC 61508-7. C.2.9.

回答 3

对于任何明智的编译器,您都应该观察到没有区别。它们应该被编译为相同的机器代码,因为它们是等效的。

With any sensible compiler, you should observe no difference; they should be compiled to identical machine code as they’re equivalent.


回答 4

因为口译员不在乎,所以这是一个风格(或偏好)问题。就我个人而言,我尽量不要对以函数基础以外的缩进级别返回值的函数做最终声明。示例1中的else会(即使只是稍微)掩盖了函数的结束位置。

根据偏好,我使用:

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

因为它遵循了将单个return语句作为函数中的最后一条语句的良好约定(如已提到的那样)以及避免命令式中间结果的良好的函数编程范例。

对于更复杂的功能,我更喜欢将功能分解为多个子功能,以避免可能的过早返回。否则,我将恢复使用称为rval的命令式样式变量。我尽量不要使用多个return语句,除非该函数是微不足道的,或者在结束之前的return语句是由于错误导致的。过早返回会突出显示您无法继续前进的事实。对于旨在分解为多个子功能的复杂功能,我尝试将它们编码为case语句(例如,由dict驱动)。

一些海报提到了运行速度。对于我来说,运行时的速度是次要的,因为如果您需要执行速度,那么Python并不是最好的语言。我将Python用作对我很重要的编码效率(即编写无错误代码)。

This is a question of style (or preference) since the interpreter does not care. Personally I would try not to make the final statement of a function which returns a value at an indent level other than the function base. The else in example 1 obscures, if only slightly, where the end of the function is.

By preference I use:

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

As it obeys both the good convention of having a single return statement as the last statement in the function (as already mentioned) and the good functional programming paradigm of avoiding imperative style intermediate results.

For more complex functions I prefer to break the function into multiple sub-functions to avoid premature returns if possible. Otherwise I revert to using an imperative style variable called rval. I try not to use multiple return statements unless the function is trivial or the return statement before the end is as a result of an error. Returning prematurely highlights the fact that you cannot go on. For complex functions that are designed to branch off into multiple subfunctions I try to code them as case statements (driven by a dict for instance).

Some posters have mentioned speed of operation. Speed of Run-time is secondary for me since if you need speed of execution Python is not the best language to use. I use Python as its the efficiency of coding (i.e. writing error free code) that matters to me.


回答 5

我个人else尽可能避免阻塞。参见反假宣传运动

另外,他们不收取“额外”费用,你知道:p

“简单胜于复杂”和“可读性为王”

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

I personally avoid else blocks when possible. See the Anti-if Campaign

Also, they don’t charge ‘extra’ for the line, you know :p

“Simple is better than complex” & “Readability is king”

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

回答 6

版本A更简单,这就是我要使用它的原因。

而且,如果您打开Java中的所有编译器警告,您将在第二个版本上收到警告,因为它是不必要的,并且增加了代码复杂度。

Version A is simpler and that’s why I would use it.

And if you turn on all compiler warnings in Java you will get a warning on the second Version because it is unnecesarry and turns up code complexity.


回答 7

我知道这个问题被标记为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

解决了没有很好的多次收益的样式问题。

I know the question is tagged python, but it mentions dynamic languages so thought I should mention that in ruby the if statement actually has a return type so you can do something like

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

Or because it also has implicit return simply

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

which gets around the style issue of not having multiple returns quite nicely.