哪一个更高性能:<= 0或<1?

早在我学习C和汇编的那一天,我们学习了使用简单比较来提高速度更好。 例如,如果你说:

if(x <= 0)

if(x < 1)

哪个会执行得更快? 我的观点(这可能是错误的)是第二个几乎总是会执行得更快,因为只有一个比较),即它是否小于1,是或否。

然而,如果数字小于0,则第一个将快速执行,因为这相当于真实,所以不需要检查等于使其等于第二个,但是,如果数目为0或更多,它将总是较慢,因为它必须进行第二次比较,看它是否等于0。

我现在正在使用C#,并且在为桌面开发速度不是问题(至少不是他的观点值得争论的程度),我仍然认为这样的论点需要考虑,因为我也在为移动设备不如台式机强大且速度在这些设备上成为问题。

为了进一步考虑, 我正在讨论整数(无小数)和数字,其中不能有负数,如-1或-12,345等(除非有错误),例如,当您处理列表或数组时有一个负数的项目,但你想检查一个列表是否为空(或者如果有问题,请将x的值设置为负值以指示错误,例如列表中有某些项目,但不能检索整个列表出于某种原因,并指出这个你设置为否定的数字,这不会像说没有项目一样)。

由于上述原因,我刻意忽略了这个明显的问题

if(x == 0)

if(x.isnullorempty())

以及用于检测没有项目的列表的其他这样的项目。

同样,为了考虑,我们正在谈论从数据库中检索项目的可能性,可能使用具有所提及功能的SQL存储过程(即标准(至少在该公司中)是返回负数以指示问题)。

所以在这种情况下,使用上面的第一项还是第二项更好?


它们是相同的。 两者都不如其他。 他们都问完全相同的问题,假设x是一个整数。 C#不是程序集。 你要求编译器生成最好的代码来获得你所要求的效果。 你没有指定它如何得到结果。

另请参阅此答案。

我的观点(这可能是错误的)是第二个几乎总是会执行得更快,因为只有一个比较),即它是否小于1,是或否。

显然这是错误的。 观察如果你认为是真的会发生什么:

<<=快,因为它提出了更少的问题。 (你的论点。)

><=速度相同,因为它提出了相同的问题,只是以相反的答案。

因此<>快! 但是同样的说法表明><更快。

“只是一个倒序的答案”似乎潜入一个额外的布尔操作,所以我不确定我是否遵循这个答案。

出于同样的原因,这是错误的(对于硅片,它有时对于软件来说是正确的)。 考虑:

3 != 4计算比3 == 4计算更加昂贵,因为它是3 != 4并带有一个反向答案,一个额外的布尔运算。

3 == 43 != 4更加昂贵,因为它是3 != 4 ,带有倒置的答案,一个额外的布尔操作。

因此, 3 != 4比它本身更昂贵。

倒置的答案只是相反的问题,而不是一个额外的布尔操作。 或者,为了更精确一点,它将比较结果与最终答案进行不同映射。 3 == 43 != 4都需要您比较3和4.该比较导致以太“等于”或“不等”。 这些问题以不同的方式将“平等”和“不平等”映射为“真”和“假”。 这两种映射都不是比另一种更昂贵。


至少在大多数情况下,不,对彼此没有好处。

A <=通常不会实现为两个单独的比较。 在典型的(例如x86)CPU上,您将有两个单独的标志,一个表示相等,一个表示负(也可以表示“小于”)。 除此之外,您将拥有依赖于这些标志组合的分支,所以<转换为jljb (如果较小则跳转或跳转 - 前者用于有符号数字,后者用于无符号数)。 A <=将转化为jlejbe (如果小于或等于,则跳转,如果小于或等于,跳转)。

不同的CPU将为指令使用不同的名称/助记符,但大多数仍具有相同的指令。 在我知道的每种情况下,所有这些都以相同的速度执行。

编辑:哎呀 - 我的意思是提到一个可能的例外情况,我上面提到的一般规则。 虽然它不完全来自< vs. <= ,如果/当您可以比较0而不是任何其他数字时,您有时可以获得一点(小小的)优势。 例如,让我们假设你有一个变量,你会倒数,直到你达到一个最小值。 在这种情况下,如果您可以倒计数到0而不是倒计数到1,那么您可能会获得一些优势。原因很简单:前面提到的标记受大多数指令影响。 假设你有类似的东西:

   do {
       // whatever
   } while (--i >= 1);

编译器可能会将其转换为如下形式:

loop_top:
    ; whatever

    dec i
    cmp i, 1
    jge loop_top

相反,如果将它与0( while (--i > 0)while (--i != 0) )进行比较,它可能会转化为类似于此的内容;

loop_top:
    ; whatever

    dec i
    jg loop_top
    ; or: jnz loop_top

这里dec设置/清除零标志以指示减量的结果是否为零,因此条件可以直接基于dec的结果,从而消除在其他代码中使用的cmp

然而,我应该补充一点,尽管这在30年前相当有效,但大多数现代编译器都可以在没有您的帮助的情况下处理这样的翻译(尽管有些编译器可能不适用,尤其是对于小型嵌入式系统)。 IOW,如果你关心一般的优化,那么你可能有一天会关心 - 但是至少对我来说,应用到C#似乎充满了怀疑。


大多数现代硬件都具有内置指令,用于检查单条指令中的低于或等于指令,其执行速度与检查低于条件的速度一样快。 适用于(很多)较旧硬件的论点不再适用 - 选择您认为最具可读性的替代方案,即更好地将您的想法传达给代码读者的方案。

链接地址: http://www.djcxy.com/p/31565.html

上一篇: Which is more performant: <= 0 or <1?

下一篇: === vs == operators performance