高效的开关声明

Sur*_*esh 3 c++ performance switch-statement

在以下两个版本的switch case中,我想知道哪个版本是高效的.

1:

string* convertToString(int i)
{
    switch(i)
    {
    case 1:
        return new string("one");
    case 2:
        return new string("two");
    case 3:
        return new string("three");
        .
        .
    default:
        return new string("error");
    }
}
Run Code Online (Sandbox Code Playgroud)

2:

string* convertToString(int i)
{
    string *intAsString;
    switch(i)
    {
    case 1:
        intAsString = new string("one");
        break;
    case 2:
        intAsString = new string("two");
        break;
    case 3:
        intAsString = new string("three");
        break;
        .
        .
    default:
        intAsString = new string("error");
        break;
    }
return intAsString;
}
Run Code Online (Sandbox Code Playgroud)

1:有多个return语句会导致编译器生成额外的代码吗?

unw*_*ind 29

这是一个过早优化的担忧.

前一种形式更清晰,源线更少,这是选择它的一个令人信服的理由(在我看来),当然.

您应该(像往常一样)对程序进行概要分析,以确定此功能是否在"热门列表"中进行优化.这将告诉您使用时是否存在性能损失break.

正如评论中指出的那样,这个代码的主要性能罪魁祸首很可能是动态分配的字符串.通常,在实现这种"整数到字符串"映射函数时,应该返回字符串常量.

  • 想要了解您的代码几乎不会过早优化.想要了解switch语句中发生的事情是非常明智的.当然,一个有意义的答案应该解释为什么性能差异不存在.但它不应该说"假装性能无关紧要,并忽略编译器对代码的作用" (3认同)

Dan*_*nas 10

两者都是.

你应该关注的是你在这里使用指针.有必要吗?谁会删除这些字符串?有没有更简单的替代方案?


phi*_*red 6

编译代码应该没有区别.然而:

  1. 您可能会发现按值返回字符串会更有效.
  2. 如果有很多字符串,请考虑使用它们预填充向量(或声明静态数组)并使用i作为索引.

  • @Vainstah RVO可能会优化副本并直接在呼叫站点构建.即使没有,std :: string也被设计为一个值类型,并且通常管理它的内部存储器,这样小的字符串就保存在静态数组中,而长字符串保存在堆上.通过在堆上创建字符串本身,您将抛弃所有优化,但仍然需要支付其开销. (5认同)
  • @Vainstah - 为什么(1)不准确和邪恶? (2认同)