可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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 an Boolean
instances. It is theoretically possible that 3 of the 4 will trigger 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.
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.
回答2:
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.
回答3:
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.
回答4:
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() ) );
}
回答5:
The last one
boolean isItTrue(arg){
return true;
}
I use Boolean
only if the method needs sometimes to return null
回答6:
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.
回答7:
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>
.
回答8:
My rules of thumb are as follows:
- The default choice is the primitive type (
boolean
).
- 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!
回答9:
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;
}