Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
max是(a,b)还是(a>;b)?a:b在Java中更快?_Java_Core_Openjdk - Fatal编程技术网

max是(a,b)还是(a>;b)?a:b在Java中更快?

max是(a,b)还是(a>;b)?a:b在Java中更快?,java,core,openjdk,Java,Core,Openjdk,Java中哪个更快?为什么 Math.max(a,b) (a>b)?a:b (这是在一次采访中被问到的。)Math.max(a,b)是一个静态函数(意味着没有虚拟调用开销),JVM可能会将其内联到与(a>b)相同的指令?a:b是Java中Math.max()的代码: public static int max(int a, int b) { return (a >= b) ? a : b; } 因此,代码的速度可能(几乎)完全相同 (老实说,如果您担心在如此低的水平上提高速度,那

Java中哪个更快?为什么

  • Math.max(a,b)
  • (a>b)?a:b
  • (这是在一次采访中被问到的。)

    Math.max(a,b)
    是一个静态函数(意味着没有虚拟调用开销),JVM可能会将其内联到与
    (a>b)相同的指令?a:b

    是Java中
    Math.max()
    的代码:

    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }
    
    因此,代码的速度可能(几乎)完全相同


    (老实说,如果您担心在如此低的水平上提高速度,那么代码中可能存在更大的问题。)

    不一样。当你在写
    (a>b)时?a:b
    您没有额外的函数调用,因此它会更快。它相当于C++中的内联。
    但这在现实生活中不会有任何区别
    Math.max(a,b)
    更具可读性,因此我会使用它。

    性能问题总是需要测试才能开始推测:

    public static void maxtest()
    {
        int res = 0;
        for( int idx = 0; --idx != 0; )
            // res = ( res > idx ) ? res : idx;
            res = Math.max( res, idx );
        System.out.println( "res: " + res );
    }
    
    在最新的1.6.1 x64服务器Sun JVM上,使用
    Math.max()
    在我的机器上运行6秒,使用
    ?:
    在我的机器上运行3.2秒。所以
    ?:
    实际上更快。与我们所希望的相反,当JIT还没有抓住一切的时候,它真的变得惊人了


    编辑:出于好奇,我还在同一台机器上用32位客户机JVM1.6.1尝试了这段代码,这两个版本都在7秒钟内运行!因此,可能不是方法调用没有内联,而是服务器JIT似乎能够为这个特定的测试用例做一些额外的优化,当涉及到方法调用时,它无法检测到这些优化。

    如果我在采访中问过这样的问题,我希望候选人告诉我,对于所有可能的a和b类型,这两个表达式可能不会给出相同的结果。

    原始问题没有指定参数的类型。这很重要,因为浮点参数的max(和min)的定义更复杂。对于浮点(double或float),Math.max方法可能较慢,但如果其中一个参数为NaN,则它也可能返回不同的结果。

    不要依赖于推测。相反,基准测试您的特定用例

    在许多其他答案中,一些容易被忽略的细节:

    虽然您可以看到
    Math.max
    的Java源代码,但实际上并不总是使用它。这种方法在几乎每个JRE中都有一个固有的版本。请参阅,以获取此类本质的列表

    据我所知,Hotspot在看到
    max
    min
    语句时会尝试一些优化;特别是优化,例如
    阵列复制
    。除此之外,它还将实际优化
    Math.max(相同,相同)


    然而,在其他情况下,它可能不会优化太多<代码>(编译器不内联JVM指令,JIT分析器内联机器代码:)@BlueRaja:我已经编辑了我的回答,因为技术上你是对的(我认为),但这实际上是问题上下文中的一个小细节。IIRC,JIT实际上不会执行任何优化,直到问题中的块被执行了很多次(数千?)次。对性能问题(特别是Java)唯一安全的答案是:“这取决于…”@TMN:好的,但是假设你在寻找一个实际的响应而不是一个法律上的响应,为什么你会为一些很少被调用的东西优化函数调用开销呢?不幸的是,我认为这归结为哪种特殊情况优化器识别。例如,假设有一条机器指令可以执行max?,优化器识别对Math.max()的调用,并用该机器指令替换它,但它不识别
    (a>b)?a:b
    。或者相反,它对Math.max()所能做的最好的处理就是将其转换为
    (a>b)?a:b
    而这种转换需要时间。我想知道面试官问这样一个问题希望得到什么。我真的很讨厌人们在面试时问语言律师问题。有人真的认为你作为一名高效程序员的能力与你记忆语言规范细节的能力密切相关吗对此问题的正确回答是(从编译器背景来看),这取决于优化器对函数调用的选择。在不知道1.执行上下文和2.优化器首选调用参数的内联方法的情况下,无法确定上述调用的速度优化。有根据的猜测(如下所示)我同意@dsimcha的观点,这些问题并不能真正说明你的能力。我可以为你编写一个jvm,其中一个速度比另一个快得多,反之亦然;)@赛斯:我希望面试官能确定面试官是否沉溺于毫无意义的微观优化。事实上,当
    a
    b
    相等时,给出问题的代码仍然会分支,这会使情况变得更糟。我知道有人会说一些关于方法查找的事情,但是,老实说,如果您关心这个问题,就不要使用Java。当有人看到
    Math.max
    时,他们知道你在做什么,这才是重要的。为什么
    a==b
    上的分支会更糟糕?让我们假设
    a
    b
    是真正随机的
    int
    s。那么
    a>b
    分支的频率就不会像
    a>=b
    一样高吗?@Sinan:当你看字节码时,你可以看到条件运算符总是分支,因此使用
    =
    而不是
    =
    会使它在值相等时使用另一条路径。当前的Java虚拟机也可以在低级别操作中获得惊人的性能,即使是C或ASM有时也很难做到这一点。高性能和高可靠性