C ++中的多个返回语句和性能

时间:2016-11-18 05:27:40

标签: c++ performance

就性能而言,是否有理由支持在函数内使用多个返回语句?

考虑下面的简单例子。

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;
}

请注意,我意识到意见在风格方面存在分歧,所以我希望能够将答案集中在表现方面。

1 个答案:

答案 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%,那么恢复ab可能会快几毫秒:因为在大多数情况下会减少一个动作。但是对于大多数应用程序而言,值不是那么可预测,并且性能差异非常小,以至于永远不会被注意到。

切换示例

对于交换机,如果有足够的值来证明小的初始开销,则编译器有可能使用branch table。对于非常大的值列表,a肯定会在密钥上使用二进制搜索提供更好的结果。

然而,这里它产生一系列比较,并且再次,开关中的值的顺序(例如,最频繁的第一个)可以比返回方法更多地影响性能。

如果您尝试your snippet on godbolt,您会发现直接返回会产生更小且明显更快的代码。这似乎是由于map类型使优化器的生命更加困难。但是我不会在更一般的情况下押注这种情况(例如,在same code for both functions中再次使用string结果)

当天的报价:

  

过早优化是所有邪恶的根源 - Donald Knuth