36

Which of the following is better in terms of performance and efficient memory usage?

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return Boolean.TRUE
}

Boolean isItTrue(arg){
    return true;
}

boolean isItTrue(arg){
    return true;
}

It should be faster and easier to work with primitive types, but on the other hand, when using a reference to a static object, no new value is created. Or is it optimized on compiler level and all true and false are replaced by references to the static objects to save memory?

georg-un
  • 1,123
  • 13
  • 24
Dima
  • 1,774
  • 5
  • 21
  • 31

9 Answers9

32

Firstly, the performance advantage of using any one over the others is most likely to be too small to be relevant. Code simplicity / readability / maintainability is a far more important ... in the vast majority of cases.


None of the examples involve creating Boolean instances.

It is theoretically possible that 3 of the 4 could trigger the initialization of the Boolean class AND that your application wouldn't otherwise have done that. In that highly unlikely event, your entire application will allocate 2 objects that wouldn't otherwise have been allocated. The initialization will probably take a few microseconds, and consume a few bytes of RAM (less than 50) in the long term.


This one will be equal to or faster than all of the others because it simply entails setting a register to zero.

boolean isItTrue(arg){
    return true;
}

Taken in isolation, this has to load a static reference from memory, rather than zero a register. However, the JIT compiler may be able to optimize this away in some circumstances.

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

On the face of it, this involve a call to Boolean.valueOf(true) to "box" the true, but the JIT compiler should be able to optimize it to the same code as the previous one by inlining the call.

Boolean isItTrue(arg){
    return true;
}

On the face of it, this involves a call to Boolean.booleanValue(Boolean.TRUE) to "unbox" the Boolean. This call can be inlined. It is also possible that the JIT compiler can avoid loading the reference to the Boolean object and fetching its value field.

boolean isItTrue(arg){
    return Boolean.TRUE
}

Bottom line is that it the relative performance of the 4 alternatives depends on how successful the JIT compiler will be in optimizing. That will depend on the context, the specific of the JIT compiler, the JVM settings, and so on. In the best case, the JIT compiler could (at least in theory) produce the same (optimal) code for all of them.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
13

If there is any performance gain it is so minuscule as to be irrelevant. Boolean.TRUE and Boolean.FALSE don't return a new object in any case.

Jim
  • 22,354
  • 6
  • 52
  • 80
12

Favour clarity for the code maintainer over such micro-optimisations. The question should not be "which is smaller/faster", first which expresses what you mean.

If the method returns a Boolean object then whoever receives needs to decide whether there is a possibility that it might be null, and that if it is null that it might mean something different from true/false, like "we don't know".

So return type of boolean, if that is what you mean, otherwise, if you want to allow Null, then Boolean.

If returning a boolean then

return true; // or false

must be better than relying on autoboxing, again for the sake of clarity as well as performance.

If returning Boolean then

return Boolean.TRUE

must be good, it just avoids creating extra garbage, much as I oppose micro-optimisation I see no value in being wilfully inefficient. I'd argue that it's also clearer in that you are conspicuously matching the return type.

djna
  • 54,992
  • 14
  • 74
  • 117
8

They will be much faster. I don't think there will be any difference between these two.

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return true;
}

But other implementation will be slower because it will be boxing and unboxing on the back end with will take some time of processor.


Edit

I have collected some facts by implementing the 4 different ways. Just want to share it with you, I don't if its the write way to do that.

Boolean isItTrue(){ 
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.844
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 10.109
Free Memory After Process --> 15940472
Memory Usage --> 90464

Boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.906
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.828
Free Memory After Process --> 15940472
Memory Usage --> 90464

Main Class

public static void main(String[] args){
    NewClass n = new NewClass();

    long sysTime = System.currentTimeMillis();

    Runtime rt = Runtime.getRuntime();
    long freeMem = rt.freeMemory();
    System.out.println( "Free Memory before start --> " + freeMem );
    for( int i = 0; i < Integer.MAX_VALUE; i++ ){
        n.isItTrue();
    }
    System.out.println( "Time taken in Secs --> " + (System.currentTimeMillis() - sysTime)/1000D);
    System.out.println( "Free Memory After Process --> " + rt.freeMemory() );
    System.out.println( "Memory Usage --> " + ( freeMem - rt.freeMemory() ) );
}
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
Talha Ahmed Khan
  • 15,043
  • 10
  • 42
  • 49
  • 1
    I do not think your claim that "They will be much faster" is correct. Any performance difference would be minute. – Paul Cager Aug 02 '11 at 14:07
  • 1
    Hay, I have added some facts after implementing it. Take a look. – Talha Ahmed Khan Aug 03 '11 at 08:25
  • 4
    Micro-benchamarks are notoriously difficult to write properly (hence the usual advice is to profile your real application). Have a look at http://www.ibm.com/developerworks/java/library/j-jtp02225/index.html and http://wikis.sun.com/display/HotSpotInternals/MicroBenchmarks – Paul Cager Aug 03 '11 at 09:11
  • 3
    This benchmark has flaws that could render the results invalid. Even if the numbers were valid, they are not representative of how the method is likely to be used, and hence of the context in which the JIT compiler would optimize them. Finally, the best-to-worst delta is 2.3 seconds for 2^31 calls == less than a nano-second == 2 or 3 CPU clock ticks on stock hardware. If that is representative, it is clearly down at the level where it will have minimal impact on the performance of a typical application. – Stephen C Aug 04 '11 at 07:23
4

The last one

boolean isItTrue(arg){
    return true;
}

I use Boolean only if the method needs sometimes to return null

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
3

My rules of thumb are as follows:

  1. The default choice is the primitive type (boolean).
  2. If I need nullability or need to store the values in a container, I use the class (Boolean).

With this in mind, my default choice would be:

boolean isItTrue(arg){
    return true;
}

As far as performance is concerned, the only thing that seems certain is that it's hard to imagine a scenario where using Boolean would be faster than using boolean. Whether it would be slower or the same depends on a lot of things and it's impossible to answer in general.

If you really care about this, profile the code where it matters!

NPE
  • 486,780
  • 108
  • 951
  • 1,012
2

By that logic, the reference to the static object itself is as costly as the truth value, if not more.

Using objects may be somewhat slower than primitives, but I wouldn't worry: the difference is irrelevant.

salezica
  • 74,081
  • 25
  • 105
  • 166
2

Use the last one (just boolean). Even if the compiler optimizes them all to the same thing, at the very least you're making the compiler's job easier (it's not an easy job you know!).

Plus it's fewer keystrokes (don't need to press shift). But really, the only reason you should use the wrapper class is when you need the ability to set it to null, and for use in generic data structures like LinkedList<E>.

tskuzzy
  • 35,812
  • 14
  • 73
  • 140
0

java.lang.Boolean takes 16 bytes.

this is the way to go if you are only looking for performance and memory size issues:

boolean isItTrue(arg){
    return true;
}
Marcus Granström
  • 17,816
  • 1
  • 22
  • 21
  • 3
    You won't save any space, because the `Boolean.TRUE` and `Boolean.FALSE` objects will be created anyway if your program causes the `Boolean` class to be initialized. – Stephen C Aug 02 '11 at 11:56
  • Will it inititalize a Boolean in the background? I was under the impression that it didn't. – Marcus Granström Aug 02 '11 at 12:05
  • Not in the background. But the JVM spec says that the initialization will occur if any static is used, any static method is called or any object instance is created (and other things). If any of those occur, the `TRUE` and `FALSE` instances will be created and the space will be used ... whether or not your application uses the instances. – Stephen C Aug 02 '11 at 12:25
  • `Boolean.TRUE` is a static field and is reused across all `true`s autoboxed to a `Boolean` – Steve Kuo Jun 21 '13 at 21:30