switch 似乎比 if 慢

2024-02-17

我很好奇速度switch,相信它“非常”快,但我有一个测试用例,似乎表明单个开关的速度大约与 4 一样快if测试,当我预期(没有充分的理由)它会像 1 次测试一样快。这是我写的两个方法来比较switch with if:

public static int useSwitch(int i) {
    switch (i) {
        case 1: return 2;
        case 2: return 3;
        case 3: return 4;
        case 4: return 5;
        case 5: return 6;
        case 6: return 7;
        default: return 0;
    }
}

public static int useIf(int i) {
    if (i == 1) return 2;
    if (i == 2) return 3;
    if (i == 3) return 4;
    if (i == 4) return 5;
    if (i == 5) return 6;
    if (i == 6) return 7;
    return 0;
}

这是我的测试代码:

long x = 0;
for (int i = 0; i < 999999; i++)
    x += useIf(i % 7); // I use "x" so calls won't get optimized out

另一个相同的循环useSwitch()

在我的机器上这些循环需要大约在同一时间完成,这是一个惊喜。
我得出的 if 数量为“4”,因为这是给定输入范围的平均值(我认为)。
如果我减少逻辑选项的数量,if版本明显更快。


我的问题是:

是那个吗switch实际上isn't这么快,还是这在某种程度上是一个“不公平”的测试?


这在某种程度上是一种不公平的比较。大部分 CPU 时间将用于处理模运算:i % 7。即使在最新最好的 CPU 上,模数也非常慢,并且执行时间可能比您尝试进行基准测试的 if() 或 switch() 实现长 20 倍。

此外,有两种不同的方法可以优化 switch 语句。一种是通过查找表,它用于顺序情况,例如您提出的情况。另一种方法是使用搜索分区树, 在适当情况下。当案件发生时会发生这种情况sparse,例如以下示例:

switch (someInt) {
    case 0:  ... break;
    case 10:  ... break;
    case 102:  ... break;
    case 6543:  ... break;
    case 19303:  ... break;
    case 19305:  ... break;
    // and so forth...
}

大多数编译器将使用展开的分区树来查找正确的情况,这在长开关上提供了非常好的平均和最坏情况跳转,以达到正确的情况。由此产生的伪代码将是这样的:

if (someInt >= 6543) {
    if (someInt >= 19303) {
        // continue tree search, etc.
    }
    else if (someInt==6543) {}
}
else if (someInt >= 0) {
    if (someInt >= 10) {
        // continue tree search, etc.
    }
    else if (someInt == 0) {} 
}
else {
    // default case handler...
}

对于只有 6-8 个案例的情况(如此处所示),它并没有多大帮助,但如果您的交换机可能有 50 多个案例,那么它会非常有帮助。线性搜索的复杂度为 O(n)(最差 50 个条件,平均 25 个),而分区树版本将接近 sqrt(n)(最差 8-9 个条件,平均 5-7 个,具体取决于编译器选择)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

switch 似乎比 if 慢 的相关文章

随机推荐

  • Openblas 没有链接到 Scipy

    我目前在 Debian Jessie 上运行 scipy 我已经从 apt get 安装了 scipy 我还从 apt 安装了 blas 和 lapack sudo apt get install python scipy libblas
  • MySQL-SUM 日期时间?

    我需要总和日期时间值 但我不知道如何做到这一点 我有桌子 我的查询 SELECT SUM h dtplay AS Time FROM tblhistory AS h tblgame AS g WHERE h idgame g id AND
  • 允许在 asp.net 文本框中使用 html

    我将 ValidateRequest false 添加到页面指令中 但页面的行为就像没有回发一样 如果我删除 html 那么它会正常回发 使用更新面板内的文本框应该不会产生影响 对吗 我正在尝试使用 html 格式将文本存储在我的数据库中
  • Qt 全局样式表加载?

    如何使用 Qt 全局加载样式表 qss 样式资源 我正在努力让事情变得比以下更有效率 middleIntText gt setStyleSheet QLineEdit border 1px solid gray border radius
  • 是否可以将 LIMIT 与子查询结果一起使用?

    当需要有序集的最后几行时 通常会创建派生表并重新排序 例如 返回自动递增表的最后 3 个元素id SELECT FROM SELECT FROM table ORDER BY id DESC LIMIT 3 t ORDER BY t id
  • \n 在 Sklabel SpriteKit 中不起作用

    我在我的游戏中使用了以下代码 问题是我无法像使用 CCLabelTTF 那样在 spritekit 中制作多行标签 有人可以帮助我吗 另外我无法在我的代码中使用 t 或 n 感谢您的提前回复 SKLabelNode winner SKLab
  • C++11 std::threads 并等待线程完成

    我有一个计时器对象向量 每个计时器对象都会启动一个模拟生长期的 std thread 我正在使用命令模式 发生的情况是每个计时器都被一个接一个地执行 但我真正想要的是一个被执行 然后一旦完成 下一个 一旦完成下一个 同时不干扰主程序的执行
  • 工具提示内的图像tiptip

    我需要在具有悬停效果的工具提示中插入图像 tel view tipTip defaultPosition top delay 400 fadeIn 400 keepAlive true activation click HTML img s
  • 多个神经网络各有一个输出还是一个有多个输出?

    我想将输入分类为三种可能性之一 使用 3 个网络 每个网络有一个输出 还是 1 个网络 每个网络有 3 个输出 更好 即 3 个网络输出0 or 1或 1 个输出长度为 3 的单热向量的网络 1 0 0 答案是否会根据输入数据分类的复杂程度
  • 无法在 Keras 中复制 matconvnet CNN 架构

    我在 matconvnet 中有以下卷积神经网络架构 我用它来训练我自己的数据 function net cnn mnist init varargin CNN MNIST LENET Initialize a CNN similar fo
  • 在 lambda 中使用 aws-sdk 吗? (AWS.ApiGatewayManagementApi 不是 Response 的构造函数)

    我正在尝试在 lambda 中使用 aws sdk 但我似乎无法弄清楚 var AWS require aws sdk AWS config update var DDB new AWS DynamoDB apiVersion 2012 1
  • 使用 Bootstrap 3 垂直居中元素

    我想将 设计 标签和 21nov 垂直居中 div class row div class col xs 6 col xs offset 1 a href job 52 span class jobtitle designer span a
  • 调整 div 大小以适应最大高度的内容

    我有一个包含动态内容的 div 当内容加载到 div 中时 我希望调整 div 大小以适应内容 但我希望此调整大小具有最大高度 如果内容需要超过这个最大高度 我希望有一个滚动条 我已经搜索过这里的问题 但无法找到我要找的东西 除了提问者回答
  • 带有子目录的 CMake

    我正在尝试设置我的项目以使用 CMake 正确编译 我的目录如下所示 root bin Where I want to build CMake from using cmake build include database database
  • Scala 抽象类型表示子类的类型

    我正在寻找一种方法来定义返回类型 T 的方法 其中 T 子类的类型 我知道我可以使用抽象类型来做到这一点 但不喜欢必须为每个子类重新定义 T 的开销 一些示例代码 object Helper def help A lt MyClass cl
  • Jquery Datepicker 更改月份后触发(月份渲染后)

    我想强调一下本月的一些日子 我可以在第一个月执行此操作 但不能在单击 下个月 或 上个月 后的新月份执行此操作 我尝试使用 onChangeMonthYear 事件 但这在新的 或上一个 月份呈现之前执行 有任何想法吗 也许你最好的选择是b
  • Windbg:psscor4 不起作用

    我搜索并尝试了很多东西 但无法让 psscor4 正常工作 当我调用 threads 我总是得到 请求ThreadStore失败 我检查的内容如下 我有一个为 X86 平台编译的 NET 4 应用程序 我使用的是Windbg版本6 2 92
  • 两组之间均匀分布的数字 (Vectorize LINSPACE) - MATLAB

    如何定义矩阵M根据M a b a 5 b from a to b分 5 步 当a and b是向量或集合 更具体地说 每一行i in M第一个值应该等于a i 和最后的值b i 其间有 5 个相等的步骤 例如 如果我有 a 0 b 10 0
  • 如何将两个 PDF 页面拼接在一起成为一张大页面?

    我有两张 36 x 48 海报 LaTeX 我想将其附加到一张 72 x 48 海报中 垂直堆叠 浏览 SO 和 GS 文档 我没有任何线索 我不是 CLI 向导 我怎样才能做到这一点 此外 该过程不应有损地压缩光栅图像 因为这将以 240
  • switch 似乎比 if 慢

    我很好奇速度switch 相信它 非常 快 但我有一个测试用例 似乎表明单个开关的速度大约与 4 一样快if测试 当我预期 没有充分的理由 它会像 1 次测试一样快 这是我写的两个方法来比较switch with if public sta