2

Assume that we have a given interface:

public interface StateKeeper {

    public abstract void negateWithoutCheck();

    public abstract void negateWithCheck();

}

and following implementations:

class StateKeeperForPrimitives implements StateKeeper {
    private boolean b = true;

    public void negateWithCheck() {
        if (b == true) {
            this.b = false;
        }
    }

    public void negateWithoutCheck() {
        this.b = false;
    }
}

class StateKeeperForObjects implements StateKeeper {
    private Boolean b = true;

    @Override
    public void negateWithCheck() {
        if (b == true) {
            this.b = false;
        }
    }

    @Override
    public void negateWithoutCheck() {
        this.b = false;
    }
}

Moreover assume that methods negate*Check() can be called 1+ many times and it is hard to say what is the upper bound of the number of calls.

  • The question is which method in both implementations is 'better' according to execution speed, garbage collection, memory allocation, etc. - negateWithCheck or negateWithoutCheck?

  • Does the answer depend on which from the two proposed implementations we use or it doesn't matter?

  • Does the answer depend on the estimated number of calls? For what count of number is better to use one or first method?

Łukasz Rzeszotarski
  • 5,791
  • 6
  • 37
  • 68
  • 3
    Can I be the first to post: Premature optimization is the root of all evil? – BlackBox Oct 04 '13 at 13:29
  • 2
    You will not see a performance difference between the two, it's as simple as that. Spend your time worrying about other things. – arshajii Oct 04 '13 at 13:30
  • 1
    And replace `if (b == true) {` with `if(b){}` – Suresh Atta Oct 04 '13 at 13:33
  • @BlackBox. Yes that for sure true. But which one you consider as 'premature' optimized with the if or without. I guess with the if looks to be 'optimized'. Of course the difference is hardly visible if ever thats also true. But what if you would have let's say 1000 call or more. of course this is a bit a theoertic question. – Łukasz Rzeszotarski Oct 04 '13 at 13:34
  • @ŁukaszRzeszotarski Do whichever you find clearest and easiest to manage. The `if`-statement there seems completely pointless as `b = false` would suffice. – arshajii Oct 04 '13 at 13:37
  • @ŁukaszRzeszotarski Although the focus is to just choose which ever way is cleaner or preferred by yourself, you also need to make sure your implementation would abide by the interface contract. If a contract states that calling method X always sets Y to false, then the one without the IF would be a must. But if the contract says, X changes Y when Z, then with the IF would be the correct one to do. – BlackBox Oct 04 '13 at 13:42
  • 1
    @ŁukaszRzeszotarski, it's not a matter of "which one you consider as 'premature' optimized". The point is that worrying about this sort of stuff is almost certainly putting the cart before the horse. **If** you have performance problems, you should figure out where they are and fix them. This problem will almost certainly not buy you any noticeable amount of improvement. Even in 1000 calls. Do you have reason to believe this code is a problem, is worth worrying about? – dcsohl Oct 04 '13 at 13:47
  • 1
    @dcsohl I agree but if I see such things in the code and I have to review them. And I see it often it is not bad to ask what kind of pattern is better or if the 'if check' is really bad. Or maybe is better ;) In my own code I prefer assignments without the check. – Łukasz Rzeszotarski Oct 04 '13 at 13:50
  • @arshajii You won't see the performance difference when it's executed a couple of times, but when you have an algorithm that executes that step millions or billions or even more, you can get a performance boost by making the right choice. – Michaël Benjamin Saerens Oct 04 '13 at 13:50
  • @MichaëlBenjaminSaerens No, even then it will likely not be noticeable. This is completely and utterly insignificant. – arshajii Oct 04 '13 at 13:52
  • @MichaëlBenjaminSaerens (arshajii) as you both see this is not a bad question. for me highly theoretic one. Assume billions of calls. So there is a difference or not. If not why? If yes why? – Łukasz Rzeszotarski Oct 04 '13 at 13:55
  • See my explanation between the answers below. Arshajii has commented his vision on it as well. – Michaël Benjamin Saerens Oct 04 '13 at 14:00
  • 1
    If you're calling it billions of times then you should benchmark the possibilities. There probably is a difference. Testing it should be easy enough. – dcsohl Oct 04 '13 at 14:07

6 Answers6

2

In general, if you need to set some state, just set the state. If, on the otherhand, you have to do something more - like log the change, inform about the change, etc. - then you should first inspect the old value.

But, in the case when methods like the ones you provided are called very intensely, there may be some performance difference in checking vs non-checking (whether the new value is different). Possible outcomes are:

1-a) check returns false
1-b) check returns true, value is assigned
2) value is assigned without check

As far as I know, writing is always slower than reading (all the way down to register level), so the fastest outcome is 1-a. If your case is that the most common thing that happens is that the value will not be changed ('more than 50%' logic is just not good enough, the exact percentage has to be figured out empirically) - then you should go with checking, as this eliminates redundant writing operation (value assignment). If, on the other hand, value is different more than often - assign it without checking.

You should test your concrete cases, do some profiling, and based on the result determine the best implementation. There is no general "best way" for this case (apart from "just set the state").

As for boolean vs Boolean here, I would say (off the top of my head) that there should be no performance difference.

alterfox
  • 1,675
  • 3
  • 22
  • 37
2

Short answer: the Without check will always be faster.

An assignment takes a lot less computation time than a comparison. Therefore: an IF statement is always slower than an assignment.

When comparing 2 variables, your CPU will fetch the first variable, fetch the second variable, compare those 2 and store the result into a temporary register. That's 2 fetches, 1 compare and a 1 store.

When you assign a value, your CPU will fetch the value on the right hand of the '=' and store it into the memory. That's 1 fetch and 1 store.

  • 1
    This is a misleading answer. You don't know how the JIT will optimize these two variants. They might even be JIT-compiled into the exact same code. Beyond that, this answer suggests that the choice here actually is a significant one, which is absolutely not true. – arshajii Oct 04 '13 at 13:54
  • But than you're depending in your compiler to optimize it correctly. There's no guaranties that it does. – Michaël Benjamin Saerens Oct 04 '13 at 14:02
  • 1
    But your statement "the Without check will always be faster" is not accurate. – arshajii Oct 04 '13 at 14:04
  • If you're fussing about details... Yes, the without check is at worst as fast as the with check. But then it'll take less time for the code optimizer to optimize your code, therefore, it's faster again than the with check... – Michaël Benjamin Saerens Oct 04 '13 at 14:24
  • @arshajii I doubt that your code optimizer will even see this. The variable b is an object variable, not a local one. Therefore, its value can be changed over the entire class. In this case, we're talking about a boolean, but integers can have a lot more values, not to speak about objects. – Michaël Benjamin Saerens Oct 04 '13 at 14:31
2

There might be a slight performance benefit in using the one with the check. I highly doubt that it matters in any real life application.

premature optimization is the root of all evil (Donald Knuth)


You could measure the difference between the two. Let me emphasize that these kind of things are notoriously difficult to measure reliably.

Here is a simple-minded way to do this. You can hope for performance benefits if the check recognizes that the value doesn't have to be changed, saving you an expensive write into the memory. So I have changed your code accordingly.

interface StateKeeper {

    public abstract void negateWithoutCheck();

    public abstract void negateWithCheck();

}

class StateKeeperForPrimitives implements StateKeeper {

    private boolean b = true;

    public void negateWithCheck() {
        if (b == false) {
            this.b = true;
        }
    }

    public void negateWithoutCheck() {
        this.b = true;
    }
}

class StateKeeperForObjects implements StateKeeper {

    private Boolean b = true;

    public void negateWithCheck() {
        if (b == false) {
            this.b = true;
        }
    }

    public void negateWithoutCheck() {
        this.b = true;
    }
}

public class Main {

    public static void main(String args[]) {

        StateKeeper[] array = new StateKeeper[10_000_000];

        for (int i=0; i<array.length; ++i)
            //array[i] = new StateKeeperForObjects();
            array[i] = new StateKeeperForPrimitives(); 

        long start = System.nanoTime();

        for (StateKeeper e : array)
            e.negateWithCheck();
            //e.negateWithoutCheck();

        long end = System.nanoTime();

        System.err.println("Time in milliseconds: "+((end-start)/1000000));
    }
}

I get the followings:

           check  no check
primitive   17ms    24ms
Object      21ms    24ms

I didn't find any performance penalty of the check the other way around when the check is always superfluous because the value always has to be changed.

Two things: (1) These timings are unreliable. (2) This benchmark is far from any real life application; I had to make an array of 10 million elements to actually see something.

I would simply pick the function with no check. I highly doubt that in any real application you would get any measurable performance benefit from the function that has the check but that check is error prone and is harder to read.

Ali
  • 56,466
  • 29
  • 168
  • 265
  • Yes. As I wrote in my comments I regard it as totally theoretic question. For example I was curious also if maybe it is optimized to the same instructions on JIT level, what someone suggested - but it seems not to happen. Thanks for the answer. – Łukasz Rzeszotarski Oct 04 '13 at 15:46
  • @ŁukaszRzeszotarski I believe the generated instructions could be the same, I don't think there is any rule forbidding it. However, as I see it from the results, the generated code differs. In any case, you can check it with [javap, the Java disassembler](http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html). – Ali Oct 04 '13 at 18:16
  • java bytecode is rather different. what I checked on my current jvm yet before I asked the question. However my guesses were if the generated machine code can be the same. What also seems not to happen regarding the test result. – Łukasz Rzeszotarski Oct 05 '13 at 11:36
  • @ŁukaszRzeszotarski I am glad you find my answer helpful. – Ali Oct 05 '13 at 11:40
1

Only today I've seen few answers and comments repeating that

Premature optimization is the root of all evil

Well obviously one if statement more is one thing more to do, but... it doesn't really matter.

And garbage collection and memory allocation... not an issue here.

Eel Lee
  • 3,513
  • 2
  • 31
  • 49
  • Your right, it doesn't matter. But I think the OP is asking if the `if`-statement could circumvent an unnecessary assignment. Again, doesn't really matter. – arshajii Oct 04 '13 at 13:39
0
  1. I would generally consider the negateWithCheck to be slightly slower due there always being a comparison. Also notice in the StateKeeperOfObjects you are introducing some autoboxing. 'true' and 'false' are primitive boolean values.

  2. Assuming you fix the StateKeeperOfObjects to use all objects, then potentially, but most likely not noticeable.

  3. The speed will depend slightly on the number of calls, but in general the speed should be considered to be the same whether you call it once or many times (ignoring secondary effects such as caching, jit, etc).

It seems to me, a better question is whether or not the performance difference is noticeable. I work on a scientific project that involves millions of numerical computations done in parallel. We started off using Objects (e.g. Integer, Double) and had less than desirable performance, both in terms of memory and speed. When we switched all of our computations to primitives (e.g. int, double) and went over the code to make sure we were not introducing anything funky through autoboxing, we saw a huge performance increase (both memory and speed).

I am a huge fan of avoiding premature optimization, unless it is something that is "simple" to implement. Just be wary of the consequences. For example, do you have to represent null values in your data model? If so, how do you do that using a primitive? Doubles can be done easily with NaN, but what about Booleans?

babernathy
  • 803
  • 2
  • 8
  • 23
0

negateWithoutCheck() is preferable because if we consider the number of calls then negateWithoutCheck() has only one call i.e. this.b = false; where as negateWithCheck() has one extra with previous one.

Chetan Gole
  • 703
  • 2
  • 14
  • 26