if语句与if-else语句,哪个更快?

2024-01-13

前几天我和一个朋友争论了这两个片段。哪个更快,为什么?

value = 5;
if (condition) {
    value = 6;
}

and:

if (condition) {
    value = 6;
} else {
    value = 5;
}

What if value是一个矩阵?

注:我知道value = condition ? 6 : 5;存在,我希望它会更快,但这不是一个选择。

Edit(由于问题暂时搁置,工作人员要求):

  • 请考虑以下任一方式回答x86 汇编由主流编译器生成(说 g++、clang++、vc、mingw)在优化和非优化版本中或MIPS组装.
  • 当程序集不同时,请解释为什么版本更快以及何时(例如“更好,因为没有分支和分支有以下问题等等”)

TL;DR:在未优化的代码中,if没有else似乎效率更高,但即使启用了最基本的优化级别,代码也基本上被重写为value = condition + 5.


I 尝试了一下 https://gcc.godbolt.org/并生成以下代码的程序集:

int ifonly(bool condition, int value)
{
    value = 5;
    if (condition) {
        value = 6;
    }
    return value;
}

int ifelse(bool condition, int value)
{
    if (condition) {
        value = 6;
    } else {
        value = 5;
    }
    return value;
}

在禁用优化的 gcc 6.3 上(-O0),相关差异为:

 mov     DWORD PTR [rbp-8], 5
 cmp     BYTE PTR [rbp-4], 0
 je      .L2
 mov     DWORD PTR [rbp-8], 6
.L2:
 mov     eax, DWORD PTR [rbp-8]

for ifonly, while ifelse has

 cmp     BYTE PTR [rbp-4], 0
 je      .L5
 mov     DWORD PTR [rbp-8], 6
 jmp     .L6
.L5:
 mov     DWORD PTR [rbp-8], 5
.L6:
 mov     eax, DWORD PTR [rbp-8]

后者看起来效率稍低,因为它有一个额外的跳跃,但两者都有至少两个和最多三个任务,所以除非你真的需要压缩每一滴性能(提示:除非你在航天飞机上工作,否则你不会,即使这样你probably不要)差异不会很明显。

然而,即使采用最低的优化级别(-O1)两个函数简化为相同:

test    dil, dil
setne   al
movzx   eax, al
add     eax, 5

这基本上相当于

return 5 + condition;

假设condition为零或一。 更高的优化级别并不会真正改变输出,除非它们设法避免movzx通过有效地归零EAX在开始时注册。


免责声明:你可能不应该写5 + condition你自己(尽管标准保证转换true到一个整数类型给出1)因为对于阅读你的代码的人(可能包括未来的你)来说,你的意图可能不会立即显而易见。这段代码的目的是表明编译器在这两种情况下生成的内容(实际上)是相同的。西普里安·托莫亚加 https://stackoverflow.com/questions/43202012/if-statement-vs-if-else-statement-which-is-faster/43202221?noredirect=1#comment73501865_43202221评论里说得很好:

a human的工作是写代码对于人类并让compiler编写代码机器.

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

if语句与if-else语句,哪个更快? 的相关文章

  • 获取 std::variant 当前持有的 typeid(如 boost::variant type())

    我已经从 boost variant 迁移到 std variant 但遇到了障碍 我在 boost type 中使用了一个很好的函数 它可以让你获取当前持有的 typeid 看https www boost org doc libs 1
  • 如何使用 MVVM 更新 WPF 中编辑的数据? [复制]

    这个问题在这里已经有答案了 我正在为聊天应用程序构建 UI 设计 在尝试更新所选联系人的消息时遇到问题 选择现有联系人 选择编辑选项 然后编辑其属性 例如用户名和图像 后 唯一进行的更改是联系人的用户名和图像 我仍然想更改 MessageM
  • 静态类变量与外部变量相同,只是具有类作用域吗?

    在我看来 静态类变量与外部变量相同 因为你只需要declare它在static int x extern int x语句 并在其他地方实际定义它 通常在 cpp 文件中 静态类变量 h file class Foo static int x
  • 访问“if”语句之外的变量

    我怎样才能使insuranceCost以外可用if陈述 if this comboBox5 Text Third Party Fire and Theft double insuranceCost 1 在 if 语句之外定义它 double
  • 找到的程序集的清单定义与程序集引用不匹配

    我试图在 C Windows 窗体应用程序 Visual Studio 2005 中运行一些单元测试 但出现以下错误 System IO FileLoadException 无法加载文件或程序集 实用程序 版本 1 2 0 200 文化 中
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 导出类时编译器错误

    我正在使用 Visual Studio 2013 但遇到了一个奇怪的问题 当我导出一个类时 它会抛出 尝试引用已删除的函数 错误 但是 当该类未导出时 它的行为会正确 让我举个例子 class Foo note the export cla
  • 如何在 Asp.net Gridview 列中添加复选框单击事件

    我在 asp 中有一个 gridview 其中我添加了第一列作为复选框列 现在我想选择此列并获取该行的 id 值 但我不知道该怎么做 这是我的 Aspx 代码
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 指向字节数组的指针

    由于 Misra C 的要求 我的一位同事想要使用指针声明 但我遇到了一些问题 Misra 安全关键指南 不会让我们纯粹的程序员使用指针 但会让我们对数组字节进行操作 他打算获取一个指向字节数组的指针 因此我们不会在堆栈上传递实际的数组 T
  • 无法加载文件或程序集“EntityFramework,版本=6.0.0.0”

    我究竟做错了什么 我该如何解决这个问题 我有一个包含多个项目的解决方案 它是一个 MVC NET 4 5 Web 应用程序 在调试模式下启动后调用其中一个项目时 出现此错误 导致此错误的项目具有以下参考 两个都是版本6 0 0 0 应用程序
  • 更改 IdentityServer4 实体框架表名称

    我正在尝试更改由 IdentityServer4 的 PersistedGrantDb 和 ConfigurationDb 创建的默认表名称 并让实体框架生成正确的 SQL 例如 而不是使用实体IdentityServer4 EntityF
  • 使用 AdHocWorkspace 会导致“不支持语言‘C#’”。

    在VS2015中使用Microsoft CodeAnalysis CSharp Workspaces的RC2 这段代码会抛出异常 var tree CSharpSyntaxTree ParseText var workspace new A
  • HTML if 语句在 CDN 失败时加载本地 JS/CSS

    当从 CDN 或任何外部服务器加载 CSS JS 文件时 有可能 即使概率很低 由于外部故障而丢失该文件 在这种情况下 html 页面将因缺乏适当的 CSS 和 JS 而被损坏 有没有一种实用的方法可以在 CDN 故障时加载本地版本 IF
  • 系统错误 124 - SHFileOperation 的 ERROR_INVALID_LEVEL

    我在使用时遇到问题SHFileOperation SHFileOperation SHFILEOPSTRUCT https stackoverflow com questions 9191415 shfileoperation shfile
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • .NET JIT 编译的代码缓存在哪里?

    NET 程序首先被编译为 MSIL 代码 当它被执行时 JIT编译器会将其编译为本机机器代码 我想知道 这些JIT编译的机器代码存储在哪里 它只存储在进程的地址空间中吗 但由于程序的第二次启动比第一次快得多 我认为即使在执行完成后 该本机代
  • ASP.NET Core Razor Page 多路径路由

    我正在使用 ASP NET Core 2 0 Razor Pages 不是 MVC 构建系统 但在为页面添加多个路由时遇到问题 例如 所有页面都应该能够通过 abc com language 访问segment shop mypage 或
  • C# 粘贴到文本框时检查剪贴板中的字符

    有没有一些方法可以在粘贴到文本框 C 之前仅检查剪贴板中的字符 Ctrl V 和右键单击 gt 粘贴 但不使用 MaskedTextbox 在文本框文本更改中添加规则以仅接受数字 例如 private string value privat
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task

随机推荐

  • RSS 是否跟踪保留或提交的内存?

    我正在 java 8 上使用不同的 jvm 选项进行实验 以降低 RSS 用于 Rss 跟踪的脚本 ps o rss o vsz o pid pid 用于设置 java 进程的 JVM 参数 XX PrintNMTStatistics XX
  • Laravel 5 中用于管理或身份验证的 Laravel 中间件

    我是 Laravel 的新手 不了解 Laravel 限制机制 我读过有关中间件的内容 但很困惑如何使用它 为什么使用它以及它如何工作 所以请指导我如何实现它以达到限制目的 即对于 auth sa 用户路由 确保您在数据库用户表中有角色列或
  • Sitecore 中子布局的多变量测试

    我过去曾尝试过这个概念 现在对在我公司的 Sitecore 网站上使用多变量测试感兴趣 我认为在很多地方我们绝对可以通过使用 A B 测试来提高销量 运行两个完全不同的模板 看看哪种布局更适合用户 在网站上运行许多不同的子布局 表单 以查看
  • PHP 中的重音符号 (`)(不是单引号)代表什么?

    在下面的示例中 第二行中的重音符号是什么意思 cmd ffmpeg i video deinterlace an ss second t 00 00 01 r 1 y vcodec mjpeg f mjpeg image 2 gt 1 re
  • 将版本放入我的 java 应用程序 - Netbeans

    有什么方法可以在 netbeans 中为我的应用程序提供版本号 然后在我的代码中访问该版本号 类似于我们在 Net 中使用的程序集号 在 java 或 netbeans 中是否有类似的东西 定义一个Implementation Versio
  • 保留 Spark Streaming 输出

    我正在从消息传递应用程序收集数据 我目前正在使用 Flume 它每天发送大约 5000 万条记录 我想用卡夫卡 使用 Spark Streaming 从 Kafka 消费 并将其保存到 hadoop 并使用 impala 进行查询 我尝试过
  • Vue.js 组件渲染后是否会触发事件?

    我在 Vue js 中有一些自定义组件 在我拥有的一个组件中有一个选择列表 我想将其呈现为Chosen http harvesthq github io chosen 选择框 我将其与 jQuery 函数一起使用 select chosen
  • 如何在 Firefox 和 Opera 中缩放 HTML 元素?

    如何在 Firefox 和 Opera 中缩放 HTML 元素 The zoom该属性在 IE Google Chrome 和 Safari 中有效 但在 Firefox 和 Opera 中无效 有什么方法可以将这个属性添加到 Firefo
  • JaxB读取类层次结构

    只是延伸使用 JaxB 解析类层次结构 https stackoverflow com questions 15676401 parsing class hierarchy using jaxb问题 想要使用 JaxB 读取以下 xml 文
  • 我需要引用命令替换吗?

    根据Google Shell 风格指南 https google github io styleguide shell xml Quoting 我应该 始终引用包含变量 命令替换 空格或 shell 元字符的字符串 除非需要小心的不带引号的
  • 是否可以让 Azure Pipeline 在提交时修改 README.md?

    我正在尝试在 Azure DevOps Repo 中自动生成和更新代码文档 我已经配置了一个管道 以便在提交到 master 分支时运行 python 脚本 该脚本从存储库中的文件中提取相关信息并创建一个 markdown 文件并将输出存储
  • 直接以 PDF 格式打印通过 JSP 动态创建的输出

    我通过 JSP 通过访问数据库动态打印报告 我正在使用Struts 框架和Java代码位于Action类中 最后通过显示输出 JSP 页面 它在屏幕上显示得很好 但在打印时却无法正常显示 我只想以 PDF 格式显示报告 而不是 JSP gt
  • 各种切入点表达式作用域意外触发多个通知调用

    背景 使用方面记录项目 例如所有标有 Log注释将信息写入日志文件 Problem 方法似乎是递归调用一级深度的 但代码没有显示任何这样的递归关系 Actual 记录结果 2018 09 25 12 17 29 155 EmailNotif
  • jquery获取光标所在元素

    我正在使用 javascript 和 jquery 为我的网站构建一个分割测试工具 现在 当光标经过预览框中的元素时 我想为每个要拆分测试的元素显示一个小悬停菜单 有可能做这样的事情吗 我尝试过这样的事情 body hover functi
  • 如何将框架添加到Swift项目中?

    我想向我的 Swift 项目添加一个库 我发现了 3 个不同的地方需要添加 我想知道执行此操作的正确方法以及每种方法的目的 常规选项卡 选择目标 gt 常规 嵌入二进制文件 链接的框架和库 构建阶段 选择目标 gt 构建阶段 嵌入框架 将二
  • 在 C 中打印声明的 char 值

    我知道字符变量的范围是从 有符号 128 到 127 和 无符号 0 到 255 char x x 128 printf d n x 但它是如何运作的呢 为什么我得到 128 for x printf是一个可变参数函数 仅提供第一个参数的精
  • 初始化 char 和 char 指针

    这些有什么区别 这个有效 char pEmpty new char pEmpty x 但是 如果我尝试这样做 char pEmpty NULL pEmpty x lt doesn t work and char pEmpty x putti
  • 在 Visual Basic 中寻找权威的 ISO 周计算器(在 Visual Studio Express 2010 中)

    我正在寻找一个明确的标准 即经过认证是正确的或经过相当彻底的测试 用于在 Visual Basic 中计算某个日期的 ISO 周 即在 Visual Studio Express 2010 Visual Basic 项目中运行 不成功 到目
  • adb shell 命令:mkdir(用于创建目录)

    我正在尝试通过 adb shell 创建目录 我必须在 etc 文件夹中创建一个目录 但没有成功 我设法弄清楚它是链接到的 system etc并尝试创建 system etc 但在这两种情况下我都得到 只读文件系统 如何使其可读可写 我尝
  • if语句与if-else语句,哪个更快?

    前几天我和一个朋友争论了这两个片段 哪个更快 为什么 value 5 if condition value 6 and if condition value 6 else value 5 What if value是一个矩阵 注 我知道va