为了账号安全,请及时绑定邮箱和手机立即绑定

如果与开关速度

如果与开关速度

紫衣仙女 2019-10-08 15:21:06
由于编译器的优化,switch语句通常比等效的if-else-if语句(如本文中所述)要快。这种优化实际上是如何工作的?有人有很好的解释吗?
查看完整描述

4 回答

?
森林海

TA贡献2011条经验 获得超2个赞

这是一个略微的简化,因为通常任何现代编译器遇到的if..else if ..序列都可能被人轻易地转换为switch语句,编译器也将如此。但是只是为了增加乐趣,编译器不受语法的限制,因此可以在内部生成“ switch”之类的语句,这些语句混合了范围,单个目标等,并且它们可以(也可以)对switch和if做到这一点。 .else语句。


顺便说一句,Konrad答案的扩展是编译器可以生成一个跳转表,但这不一定能保证(也不可取)。出于各种原因,跳转表对现代处理器上的分支预测器不利,而表本身对缓存行为不利。


switch(a) { case 0: ...; break; case 1: ...; break; }

如果编译器为此实际生成了一个跳转表,则if..else if..由于跳转表使分支预测失败,因此替代样式代码的运行速度可能会更慢。


查看完整回答
反对 回复 2019-10-08
?
波斯汪

TA贡献1811条经验 获得超4个赞

Switch / case语句通常可以更快地达到1级深度,但是当您开始使用2级或2级以上语句时,switch / case语句的开始时间是嵌套if / else语句的2-3倍。


本文有一些速度比较,突出显示了嵌套此类语句时的速度差异。


例如,根据他们的测试,示例代码如下:


if (x % 3 == 0)

            if (y % 3 == 0)

                total += 3;

            else if (y % 3 == 1)

                total += 2;

            else if (y % 3 == 2)

                total += 1;

            else

                total += 0;

        else if (x % 3 == 1)

            if (y % 3 == 0)

                total += 3;

            else if (y % 3 == 1)

                total += 2;

            else if (y % 3 == 2)

                total += 1;

            else

                total += 0;

        else if (x % 3 == 2)

            if (y % 3 == 0)

                total += 3;

            else if (y % 3 == 1)

                total += 2;

            else if (y % 3 == 2)

                total += 1;

            else

                total += 0;

        else

            if (y % 3 == 0)

                total += 3;

            else if (y % 3 == 1)

                total += 2;

            else if (y % 3 == 2)

                total += 1;

            else

                total += 0;

在等效的switch / case语句运行一半的时间内完成了:


switch (x % 3)

    {

        case 0:

            switch (y % 3)

            {

                case 0: total += 3;

                    break;

                case 1: total += 2;

                    break;

                case 2: total += 1;

                    break;

                default: total += 0;

                    break;

            }

            break;

        case 1:

            switch (y % 3)

            {

                case 0: total += 3;

                    break;

                case 1: total += 2;

                    break;

                case 2: total += 1;

                    break;

                default: total += 0;

                    break;

            }

            break;

    case 2:

            switch (y % 3)

            {

                case 0: total += 3;

                    break;

                case 1: total += 2;

                    break;

                case 2: total += 1;

                    break;

                default: total += 0;

                    break;

            }

            break;

    default:

        switch (y % 3)

        {

            case 0: total += 3;

                break;

            case 1: total += 2;

                break;

            case 2: total += 1;

                break;

            default: total += 0;

                break;

        }

        break;

    }

是的,这是一个基本的例子,但它说明了这一点。


因此,对于仅深一层的简单类型,可能会使用switch / case来得出结论,但对于更复杂的比较和多个嵌套的层,则使用经典的if / else构造?


查看完整回答
反对 回复 2019-10-08
?
MM们

TA贡献1886条经验 获得超2个赞

不匹配的统计信息可能不好。

如果您实际下载源,则在if和switch情况下,不匹配值都已知为21。编译器应该能够抽象出来,知道应该始终运行哪个语句,并且CPU应该能够正确分支预测。

在我看来,更有趣的情况是并非所有情况都中断了,但是这可能不是实验的范围。


查看完整回答
反对 回复 2019-10-08
  • 4 回答
  • 0 关注
  • 687 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信