java CONSTANT.equals(VARIABLE) 比 VARIABLE.equals(CONSTANT) 快吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10911068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:03:48  来源:igfitidea点击:

Is CONSTANT.equals(VARIABLE) faster than VARIABLE.equals(CONSTANT)?

java

提问by Ashish Agarwal

I had an interesting conversation with one of my team mate.

我和我的一位队友进行了一次有趣的交谈。

Is CONSTANT.equals(VARIABLE)faster than VARIABLE.equals(CONSTANT)in Java?

CONSTANT.equals(VARIABLE)速度比VARIABLE.equals(CONSTANT)在Java中?

I suspect this to be a false statement. But I am trying to figure out what should be qualitative reasoning behind this?

我怀疑这是一个虚假陈述。但我想弄清楚这背后的定性推理是什么?

I know in both the cases the performance will not differ to any kind of significant state. But it was a recommendation under BEST PRACTICES which is making me uncomfortable. That's the reason I am looking towards a good reasoning that I want to present with this case.

我知道在这两种情况下,性能不会因任何类型的重要状态而有所不同。但这是最佳实践下的建议,这让我感到不舒服。这就是我希望在这个案例中提出一个好的推理的原因。

Please HELP

请帮忙

回答by AlexR

Interesting question. Here is the test I wrote:

有趣的问题。这是我写的测试:

public class EqualsTest {
    public static String CONST = "const";
    public void constEqVar(String var) {
        CONST.equals(var);
    }
    public void varEqConst(String var) {
        var.equals(CONST);
    }
}

Then I compiled it using javac: javac EqualsTest.javaand disassembled it using javap: javap -c EqualsTest.

然后,我使用javac编译它:javac EqualsTest.java使用反汇编它javapjavap -c EqualsTest

Here is the relevant snippet of javap output:

这是 javap 输出的相关片段:

public void constEqVar(java.lang.String);
  Code:
   0:   getstatic       #2; //Field CONST:Ljava/lang/String;
   3:   aload_1
   4:   invokevirtual   #3; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   7:   pop
   8:   return

public void varEqConst(java.lang.String);
  Code:
   0:   aload_1
   1:   getstatic       #2; //Field CONST:Ljava/lang/String;
   4:   invokevirtual   #3; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   7:   pop
   8:   return

As you can see the only difference between theses 2 methods is order of operations: getstatic and then aload_1 in first case and aload_1 + getstatic in second case.

正如您所看到的,这两种方法之间的唯一区别是操作顺序:在第一种情况下为 getstatic 然后 aload_1,在第二种情况下为 aload_1 + getstatic。

Pretty obvious that the execution time should not depend on this order.

很明显,执行时间不应该取决于这个顺序。

The only reason to prefer const.equals(var)rather than var.equals(const)is to avoid NullPointerException.

更喜欢const.equals(var)而不是var.equals(const)避免的唯一原因NullPointerException

回答by Peter Lawrey

For me its not a speed issue, its a relability issue.

对我来说,这不是速度问题,而是可靠性问题。

e.g.

例如

"Hello".equals(a); // will never throw a NPE
a.equals("Hello"); // can throw an NPE.

You may prefer it to blow up when a is nullbut usually I don't.

你可能更喜欢它在 a 时爆炸,null但通常我不会。

回答by tibo

That depends only on the implementation of the equals method. It could be quicker, it could be the slower and it could be the same... Often it is the same. Also it does not depend on the fact that one is a variable and the other a constant but on the content both objects.

这仅取决于 equals 方法的实现。它可以更快,也可以更慢,也可以相同……通常是相同的。此外,它不依赖于一个是变量而另一个是常量的事实,而是取决于两个对象的内容。

One advantage of Constant.equals(variable) is that you can't have a NullPointerException on the .equals

Constant.equals(variable) 的一个优点是你不能在 .equals 上有 NullPointerException

回答by Mats Adborn

Made a simple test with Strings:

用字符串做了一个简单的测试:

final String constHello = "Hello";
final int times = 1000000000;

long constTimeStart = System.nanoTime();

for (int i = 0; i < times; ++i) {
    constHello.equals("Hello");
}

long constTimeStop = System.nanoTime();

System.out.println("constHello.equals(\"Hello\"); " + times + " times: " + (constTimeStop - constTimeStart) + " ns");


constTimeStart = System.nanoTime();

for (int i = 0; i < times; ++i) {
    "Hello".equals(constHello);
}

constTimeStop = System.nanoTime();

System.out.println("\"Hello\".equals(constHello); " + times + " times: " + (constTimeStop - constTimeStart) + " ns");

Edit:As mentioned in the comments below, this wasn't a good way of doing micromeasurements. Switching which part of the code which was going to be executed first proved that warm up time played a significant role here. The first test always runs slower. Repeating the test multiple times in the same code to quickfix this makes the results more or less the same.

编辑:正如在下面的评论中提到的,这不是进行微量测量的好方法。切换将首先执行的代码部分证明预热时间在这里发挥了重要作用。第一个测试总是运行得更慢。在同一代码中多次重复测试以快速修复这会使结果或多或少相同。

回答by Vinod Pattanshetti

If we compare CONSTANT key(Left side of equals method)with any Object(Right side of equals method)then compiler can do check comparison and give the expected result, but if we do vice versa Object((Left side of equals method))comparison with Constant key((Right side of equals method))then your program might through the NULL POINTER EXCEPTION.

如果我们将CONSTANT 键(等于方法的左侧)与任何对象(等于方法的右侧)进行比较,那么编译器可以进行检查比较并给出预期的结果,但如果反之亦然,则对象((等于方法的左侧))Constant key((Right side of equals method))进行比较,那么您的程序可能会通过NULL POINTER EXCEPTION

public static void main(String[] args) {
    String CONSTANT_KEY = "JAVA";
    String string = null;

    // CASE 1
    if (CONSTANT_KEY.equals(string)) {
        System.out.println("I am in if block");
    }

    // CASE 2   
    if (string.equals(string)) {
        System.out.println("I am in if block");
    }
}

In above code case 1 is always safe to compare the objects to avoid NULL POINTER EXCEPTION instead of case 2.

在上面的代码中,情况 1 总是可以安全地比较对象以避免 NULL POINTER EXCEPTION 而不是情况 2。

回答by Govind

One good comparison can be:

一个很好的比较可以是:

private static String EXAMPLE = "Example";
private String obj = null;

case 1:

情况1:

if(obj.equals(EXAMPLE) {
}

This is throw null pointer exception..

这是抛出空指针异常..

case 2 :

案例2:

if(EXAMPLE.equals(obj)) {
}

This will not throw null pointer exception..

这不会抛出空指针异常..

回答by Ashish Agarwal

I guess the code in java.lang.Stringsupports my answer:

我猜中的代码java.lang.String支持我的回答:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}