例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
当前回答
从理论上讲,反转if可以提高分支预测的命中率,从而提高性能。在实践中,我认为很难确切地知道分支预测将如何表现,特别是在编译之后,所以我不会在日常开发中这样做,除非我正在编写汇编代码。
更多关于分支预测的信息。
其他回答
方法中间的返回并不一定是坏的。如果能使代码的意图更清晰,那么立即返回可能会更好。例如:
double getPayAmount() {
double result;
if (_isDead) result = deadAmount();
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetired) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;
};
在这种情况下,如果_isDead为真,我们可以立即退出该方法。也许这样结构会更好:
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
我从重构目录中挑选了这段代码。这种特殊的重构被称为:用保护子句替换嵌套条件句。
这完全是有争议的。在提前返回的问题上,“程序员之间没有达成一致”。据我所知,这总是主观的。
这是有可能的,因为最好有条件,所以它们通常是真的;也可以说,它更清晰。另一方面,它确实创建了嵌套测试。
我不认为你会对这个问题得到一个结论性的答案。
There are several advantages to this sort of coding but for me the big win is, if you can return quick you can improve the speed of your application. IE I know that because of Precondition X that I can return quickly with an error. This gets rid of the error cases first and reduces the complexity of your code. In a lot of cases because the cpu pipeline can be now be cleaner it can stop pipeline crashes or switches. Secondly if you are in a loop, breaking or returning out quickly can save you a lots of cpu. Some programmers use loop invariants to do this sort of quick exit but in this you can broke your cpu pipeline and even create memory seek problem and mean the the cpu needs to load from outside cache. But basically I think you should do what you intended, that is end the loop or function not create a complex code path just to implement some abstract notion of correct code. If the only tool you have is a hammer then everything looks like a nail.
就我个人而言,我倾向于只有一个退出点。如果您保持方法的简短和切中要害,这很容易实现,并且它为下一个处理您的代码的人提供了可预测的模式。
eg.
bool PerformDefaultOperation()
{
bool succeeded = false;
DataStructure defaultParameters;
if ((defaultParameters = this.GetApplicationDefaults()) != null)
{
succeeded = this.DoSomething(defaultParameters);
}
return succeeded;
}
如果您只是想在函数退出之前检查函数中某些局部变量的值,这也是非常有用的。您所需要做的就是在最终返回值上放置一个断点,并保证能够命中它(除非抛出异常)。
从理论上讲,反转if可以提高分支预测的命中率,从而提高性能。在实践中,我认为很难确切地知道分支预测将如何表现,特别是在编译之后,所以我不会在日常开发中这样做,除非我正在编写汇编代码。
更多关于分支预测的信息。