-1

I understand that == checks for reference equality and equals checks for value equality.

I just want to know if I do

  1. if(int_value == int_value)

  2. if(int_value.equals(int_value))

These are just notion of actual code; not actual code.

in java, which one will be computed faster?

Yesterday one of my coding solution showed "Time Exceed" when I used == and worked when I switched to equals. So yes it matters when you are using equality checking a million times in your code.

Rishi
  • 1,646
  • 2
  • 15
  • 34
  • 2
    how critical is the milliseconds delta between those? – ΦXocę 웃 Пepeúpa ツ Jul 25 '17 at 10:04
  • 4
    your second example doesn't even compile. because `int` is primitive and not an object – Lino Jul 25 '17 at 10:05
  • Assuming you wish to compare `anInteger.equals(Integer other)` to `anInt == anotherInt`, the primitive comparison is faster – Aaron Jul 25 '17 at 10:07
  • `equals()` has the overhead of calling the method. Because `Object#equals()` just compares by reference (`==`) – Lino Jul 25 '17 at 10:08
  • 1
    Why not benchmarking it? – Davide Spataro Jul 25 '17 at 10:08
  • If you meant to use a complex type in the second example (which i assume), the first one is faster. Calling methods always takes some time. The second one will call some methods internally and then do the same thing the first example does. – bkis Jul 25 '17 at 10:09
  • @mumpitz Unless the JIT compiler optimizes the method call by inlining it, in this case, removing the method call overhead. – HatsuPointerKun Jul 25 '17 at 10:12
  • Alright [here's a benchmark](https://ideone.com/BRDVnb), just did it quickly feel free to build on it. As expected the primitive version is faster, but the difference is negligible. – Aaron Jul 25 '17 at 10:19
  • @Aaron Your benchmark is flawed for a number of reasons. JVM experiences some warm-up effects which you don't take into account. You're performing reference equality on the Integers which is never something you want to do. Your "equal primitive comp" is actually exactly the same as your "unequal object comp". – Michael Jul 25 '17 at 10:24
  • Can someone remove the downvote? – Rishi Jul 25 '17 at 10:28
  • It doesn't make sense to even ask the question unless the semantics of `==` and `equals()` are identical, which is only true in certain specialised cases. – user207421 Jul 25 '17 at 10:34
  • @EJP It does Sir; Every single doubt which comes in mind of new programmers is worth of taking care. So it does Sir :) – Rishi Jul 25 '17 at 10:46
  • 2
    @Michael thanks for pointing out I copy pasted too quickly and forgot to replace the `==` by `.equals` in the Integer cases. I can't believe I did that, it misses the whole point... I've fixed it in [this benchmark](https://ideone.com/k0gYu8) and it shows a much greater time for Integer comparison. About JVM warmup, isn't that (one of) the point of running 10000 iterations? – Aaron Jul 25 '17 at 10:47
  • 2
    @Aaron Nope. Running 10k iterations is about increasing the reliability of the results - it evens out the variation between iterations, if you like. If the JVM is still warming up through the first iterations of a test case, the results will be skewed to be slower than they really are. You need the JVM to be fully warmed up before you measure anything. [This article is reasonably good](https://www.ibm.com/developerworks/library/j-benchmark1/index.html) at explaining it. – Michael Jul 25 '17 at 10:56
  • @Michael thanks for the resource, I'll have to look into it. For now I've tried to implement the warmup phase but [it reverses the result](https://ideone.com/17p2KF) so much that I have a hard time believing it's the result of JIT optimization. I guess I should use randomized integers to avoid what looks like caching – Aaron Jul 25 '17 at 11:07
  • @Aaron Take the `10 * ` out and that doesn't happen. I have no idea why though. – Michael Jul 25 '17 at 11:18
  • @Michael Wouldn't it be because the whole code then runs before the JVM has finished optimizing the task? If so, it underlines that JVM warmup is extremely important for benchmark and also shows that in *some cases* `.equals` can be optimized to run faster than reference comparisons. The "some cases" here is important though, and comparing the same numbers thousands of time isn't a very realistic case. I'll do some more tinkering in the next hours. – Aaron Jul 25 '17 at 11:26

4 Answers4

4

The following is not valid:

int i;
int j;

if (i.equals(j))

because primitives are not objects. They have no methods at all; not even equals.

Java has the concept of boxed primitives which are classes which encapsulate a primitive and provide methods you can call. For int the box class is Integer. Using these classes is always slower than using the primitive version but it's sometimes unavoidable. There is an overhead, however slight, to creating objects and making method calls. Primitive values don't suffer from this.

Basically, use primitives unless there's a compelling reason not to.


If the types involved are Integer:

Integer i;
Integer j;

if (i.equals(j))

then you do have an equals method. However, you have (effectively) no choice but to call equals to make this comparison because == is reference equality. You can read more about that here: How to properly compare two Integers in Java? John Skeet's answer talks a little bit about the most efficient way to compare two Integers.

Michael
  • 41,989
  • 11
  • 82
  • 128
4

Is == checking is slower than equals() in Java?

Comparing two object references is most of time faster but it doesn't make always sense to compare objects in this way.

1) As you compare two int (primitive), the == operator should be favored :

int i = ...;
if(i == 1){

It is the most natural and efficient way.

2) As you compare two Integer(object), the equals()way should be favored:

Integer i =  ...
Integer j =  ...   
if(i.equals(j)){

You have not to use == as == will compare the identity of the objects and it could work in some range but not in all and it depends also on how Integers were instantiated.
So just don't use == in this case.

3) As you compare an Integer with an int, the equals()way should be avoided.

Integer i = ...
if(i.equals(1)){

works but should be avoided as it boxes int 1 to a Integer 1 before invoking equals().
And the equals() method invokes intValue() on the passed Integer argument to equals(). In brief, it performs checks and computations that could be avoided.

You have two ways to handle this comparison case that should have similar performance :

  • Using the == comparison :

    Integer i = ... if (a==1){

    It unboxes the Integer to an int and compares directly the int value with ==

  • using the intValue() of the wrapper and comparing then two primitive ints with ==** (we come back to the first case) :

    Integer i = if(i.intValue() == 1)){

Generally, the automatic unboxing performed by the JVM from an Integer to an int invokes intValue() .

davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

It's the other way around. When you compare with == it just checks the reference, but when you call equals it has a cost of function call atleast.

For custom objects having a bunch of fields, it can be even costlier if you have an implementation of equals which checks for equality of other fields internally.

Mritunjay
  • 25,338
  • 7
  • 55
  • 68
  • _but when you call equals it has a cost of function call atleast_ Not if the JIT compiler optimizes by inlining the equals method, which will remove the function call – HatsuPointerKun Jul 25 '17 at 10:14
  • @HatsuPointerKun, Yeah True, but what if have an object with having equals method which checks for few more conditions. As I have mentioned in second part. – Mritunjay Jul 25 '17 at 10:30
  • Exactly. The main difference in performance will be explained by the equals method code itself – HatsuPointerKun Jul 25 '17 at 10:46
0

Type int is faster than Class Integer. You cant do .equals of int type : error: int cannot be dereferenced

Miguel M
  • 61
  • 4