在iPhone中三元运算是否优于“ if / else”

问题描述

|| 我的程序中包含以下代码块:
if (x > 0) {
    a = 1;
    b = 4;
} else {
    a = 2;
    b = 3;
}
可以这样编写三元操作:
a = (x > 0) ? 1 : 2;
b = (x > 0) ? 4 : 3;
结果是等效的,但这是我的应用程序中非常关键的一部分,每秒运行数千次。我想挤一些微秒,因为这种方法会增长一点。 我的问题:在ARM级别上,哪一个更快?我相信第一个创建分支指令。但是三元运算呢?它也成为iPhone的分支吗?还是iPhone的ARM有邪恶的操作码来完成这项工作? 顺便说一句,我还看到了这样的邪恶技巧:
a = (x > 0) * 1 + (x <= 0) * 2;
这真的更快吗?     

解决方法

        编辑: 只需使用GCC / LLVM,不同的优化并查看ARM6和ARM7汇编来编译示例,以下是我的结论: ARM-ASM取决于GCC / LLVM和目标体系结构而有所不同 但是,当使用最高优化级别时,无论编译器/架构是什么,它都会为if和三元生成完全相同的汇编代码。 (是的,比较了几对;) 这是使用LL3 / ARM7的最简洁的结果,使用您提到的
IT
指令表示if和三进制:
MOVS    R1,#2
CMP     R0,#0
IT GT
MOVGT   R1,#1
MOV.W   R2,#3
IT GT
MOVGT   R2,#4
编辑结束 只是在该主题上进行了一些搜索,即使有人认为三元数的优化效果不佳,而最相关的则是三元数产生相同的汇编代码。 请注意,它可能会随着改变: 编译器GCC,LLVM ... 优化级别 我现在有点反汇编代码的懒惰,但是也许以后我会编辑答案。 因此,我认为djna是正确的,将2 *
(x>0)
设为适当,如果不进行优化,那真的会令人惊讶,这是相同的。 在那之后,三元与否,取决于品味。 当在代码中有意义并且可读时,我更喜欢三元。 关于第二个示例,这是一个利用true == 1 / false == 0 ...的事实的技巧。 有趣,但我不想保留该代码。     ,        没有。 代码高尔夫没有赢家。 可读性强。 因此,在这种情况下,使用传统条件块的第一个示例的可读性约为7099092034902倍。甚至对编程非常熟悉的任何人都将能够了解正在发生的事情。 在后一个示例中……上帝,那是什么!     ,        一个聪明的编译器可以为两个代码产生相同的输出。 非智能编译器会导致(X> 0)在三元运算符情况下被评估两次,因此速度会更慢!     ,        经过多年优化软件的努力,我敢打赌您上面发布的那小块并不是您真正的问题。我认为我们需要将整个方法与一些分析结果(在进行优化时,测量是一切)一起看待,以便对其进行更好的处理。 要回答您自己的问题,请选择每个选项并针对1000万次调用进行概要分析(在上述片段中,只有一千个不会告诉您太多信息)。这将告诉您哪种方式最适合速度,没有必要再进行第二次猜测。     ,           我的问题:在ARM级别上,哪一个更快? 为什么不编写一个简单的测试程序来测量每个块的100000次调用的执行速度?     ,        没什么区别,gcc会将简单的if和三元运算符编译到同一代码中。如果您确实想在ARM asm级别上优化代码,则可以通过使用条件ARM asm代码来避免分支,从而显着提高速度。但是,为此,您需要分析代码并找出真正需要它的位置。然后,您将只需要为代码中的热点手动编写ARM asm代码。基本上,如果您不需要极端的性能改进,则只需使用编译器提供的功能,因为在大多数情况下,编译器都可以很好地完成工作。     ,        增强可读性,您不是编译器     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...