就性能而言,是否有理由支持在函数内使用多个返回语句?
考虑下面的简单例子。
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
int min2(int a, int b)
{
int result;
if (a < b)
result = a;
else
result = b;
return result;
}
enum class Fruit { Apple, Orange, Banana };
std::string fruitToString(Fruit f)
{
switch (f)
{
case Fruit::Apple:
return "Apple";
case Fruit::Orange:
return "Orange";
case Fruit::Banana:
return "Banana";
default:
return "Unknown Fruit";
}
}
std::string fruitToString2(Fruit f)
{
std::string result;
switch (f)
{
case Fruit::Apple:
result = "Apple";
break;
case Fruit::Orange:
result = "Orange";
break;
case Fruit::Banana:
result = "Banana";
break;
default:
result = "Unknown Fruit";
}
return result;
}
请注意,我意识到意见在风格方面存在分歧,所以我希望能够将答案集中在表现方面。
答案 0 :(得分:3)
返回或不返回,这就是问题所在。是吗?
对于第一个代码段,优化器可能会为两个备选方案生成相同的代码。例如,对于GCC 6.2(see online compiler):
Select
顺便说一下,它仍然是相同的汇编程序代码:
cmp edi, esi
mov eax, esi
cmovle eax, edi
ret
此处,效果与值的统计分布更相关:如果int min3(int a, int b)
{
return a < b? a:b;
}
最大为99%,那么恢复a
和b
可能会快几毫秒:因为在大多数情况下会减少一个动作。但是对于大多数应用程序而言,值不是那么可预测,并且性能差异非常小,以至于永远不会被注意到。
切换示例
对于交换机,如果有足够的值来证明小的初始开销,则编译器有可能使用branch table。对于非常大的值列表,a
肯定会在密钥上使用二进制搜索提供更好的结果。
然而,这里它产生一系列比较,并且再次,开关中的值的顺序(例如,最频繁的第一个)可以比返回方法更多地影响性能。
如果您尝试your snippet on godbolt,您会发现直接返回会产生更小且明显更快的代码。这似乎是由于map
类型使优化器的生命更加困难。但是我不会在更一般的情况下押注这种情况(例如,在same code for both functions中再次使用string
结果)
当天的报价:
过早优化是所有邪恶的根源 - Donald Knuth