Java 什么更快:相等检查还是符号检查
我想知道哪种操作更快:Java 什么更快:相等检查还是符号检查,java,performance,comparison,equality,cpu-architecture,Java,Performance,Comparison,Equality,Cpu Architecture,我想知道哪种操作更快: int c = version1.compareTo(version2); 这个 if (c == 1) 还是这个 if (c > 0) 符号比较是否只使用一位检查,相等比较是否使用减法,还是不正确?可以肯定的是,假设我们在x86上工作 另外,这不是一个优化问题,只是想知道它是如何工作的。“它是如何工作的”实际上取决于平台(例如,硬件指令集)、您使用的Java版本和上下文(例如,在程序之前和之后发生了什么) 值得一提的是,有一个java命令行选项,它将转储特定
int c = version1.compareTo(version2);
这个
if (c == 1)
还是这个
if (c > 0)
符号比较是否只使用一位检查,相等比较是否使用减法,还是不正确?可以肯定的是,假设我们在x86上工作
另外,这不是一个优化问题,只是想知道它是如何工作的。“它是如何工作的”实际上取决于平台(例如,硬件指令集)、您使用的Java版本和上下文(例如,在程序之前和之后发生了什么)
值得一提的是,有一个java
命令行选项,它将转储特定方法的JIT编译本机代码:
Comparable.compareTo(T)
方法不能保证返回-1、0或+1。规范说它可以返回任何整数。因此,测试c==1
可能不起作用。。。取决于比较的实现方式。它的工作方式实际上取决于平台(例如,硬件指令集)、您使用的Java版本以及上下文(例如,在程序之前和之后发生了什么)
值得一提的是,有一个java
命令行选项,它将转储特定方法的JIT编译本机代码:
但是,您应该知道这两个测试并不等同。具体来说,
Comparable.compareTo(T)
方法不能保证返回-1、0或+1。规范说它可以返回任何整数。因此,测试c==1
可能不起作用。。。取决于compareTo的实现方式。假设这些操作在没有任何优化的情况下被JIT成x86操作码,则没有区别。这两种情况下可能出现的x86伪汇编代码段可能是:
cmp i, 1
je destination
以及:
cmp
操作在两个操作数(寄存器i
和立即数0
之间执行减法运算,丢弃结果并设置一些标志:正、负、溢出等
然后,在一种情况下,如果两个操作数equal,则这些标志用于触发条件跳转(即如果条件跳转),在第二种情况下,如果第一个操作数g大于第二个操作数,则使用这些标志
同样,这没有考虑任何软件(JVM方面)和/或硬件优化。事实上,x86_64体系结构有一个复杂的管道,具有高级分支预测和无序执行,这些微基准几乎没有意义。我们早已不再计算指令了。假设这些操作在没有任何优化的情况下被JIT成x86操作码,那么就没有什么区别了。这两种情况下可能出现的x86伪汇编代码段可能是:
cmp i, 1
je destination
以及:
cmp
操作在两个操作数(寄存器i
和立即数0
之间执行减法运算,丢弃结果并设置一些标志:正、负、溢出等
然后,在一种情况下,如果两个操作数equal,则这些标志用于触发条件跳转(即如果条件跳转),在第二种情况下,如果第一个操作数g大于第二个操作数,则使用这些标志
同样,这没有考虑任何软件(JVM方面)和/或硬件优化。事实上,x86_64体系结构有一个复杂的管道,具有高级分支预测和无序执行,这些微基准几乎没有意义。我们早已不再计算指令了。compareTo()的精彩之处,但这只是一个例子,处理器指令是主要的objective@AdamSkywalker-我添加了一个链接,这样您就可以满足对本机代码的好奇心。。。关于compareTo()的内容很好,但这只是一个例子,处理器指令是主要的objective@AdamSkywalker-我添加了一个链接,这样您就可以满足对本机代码的好奇心。。。所有这些操作都是O(1),发音为Big-O of 1。也就是说,如果一个人执行3行代码,或者一个人执行2行代码,其实并不重要,性能更取决于CPUelse@DanCiborowski-MSFT我认为在这里谈论大O是不对的,因为一个操作的执行可能取决于内存访问的数量,缓存命中/未命中和许多其他影响性能的因素,同时仍在谈论单个指令。@DanCiborowski MSFT这类影响甚至可能不是O(1)(例如,等待缓存加载时暂停)。@DanCiborowski MSFT O(1)是一个抽象概念,对于这个问题来说太高了。我们认为所有“基本”操作为O(1)的唯一原因是不再复杂分析复杂化,希望这些差异甚至超过执行次数。例如,
x+y
和x/y
对您来说可能是O(1),但后者对CPU来说肯定更重。这就是为什么我将其作为注释而不是答案。关注注释的第二部分,关于CPU是这些操作之间性能差异的最重要部分。所有这些操作都是O(1),发音为Big-O of 1。也就是说,如果一个人执行3行代码,或者一个人执行2行代码,其实并不重要,性能更取决于CPUelse@DanCiborowski-MSFT我认为在这里谈论大O是不对的,因为一个操作的执行可能取决于内存访问的数量,缓存命中/未命中和许多其他影响性能的因素,同时仍在谈论单个指令。@DanCiborowski MSFT这类影响甚至可能不是O(1)(例如,等待缓存加载时暂停)。@DanCiborowski MSFT O(1)是一个抽象概念,对于这个问题来说太高了。我们认为所有“基本”运算为O(1)的唯一原因是不编译。