Is there a performance cost to autobox a primitive literal?
Asked Answered
P

1

6

Say I have the following code:

Map<String, Boolean> map = ...
map.put("foo", true);

Theoretically, true will have to be autoboxed, resulting in a slight performance hit versus inserting Boolean.TRUE. But since we're dealing with a literal value, is it possible for the compiler to replace the primitive literal with a boxed literal so there's no extra runtime overhead?

Before anyone attacks me, I would generally opt for the primitive literal for the sake of code clarity, even if there was a tiny performance cost. This question is mostly theoretical.

Pseudohermaphroditism answered 8/1, 2016 at 23:8 Comment(7)
the key to understanding any performance related question will always start with a test. To improve your question, show a timing test that gives results of a performance analysis. For instance, you could write a timed for-loop that puts 100K entries into a map and prints how long it took, and do the same for different arguments to map.putSqueak
You could use a Boolean constant; map.put("foo", Boolean.TRUE);Orientalism
@ElliottFrisch I know. My question is whether it would help at all.Pseudohermaphroditism
@assylias this is a question tailor made for you to answer; by showing the byte code.Mensch
@bohemian no bytecode analyser on my mobile - such a shame...Hypodermis
@Hypodermis I'm mobile too :( I've considered creating an app to compile and run java - and why not show byte code too.Mensch
@Pseudohermaphroditism an alternative is also to use a static import and replace true with TRUE.Hypodermis
I
5

Yes, there is a small performance hit. In order to box a primitive, the wrapper type's valueOf() method is used. Because this is such a simple method for Boolean (return x ? TRUE : FALSE;), a JIT might be able to effectively inline the result; currently the Java compiler, however, does not. (Use of valueOf() isn't required by the JLS, so an optimization for Boolean could be introduced.)

For other types, it's more complicated. For example, Integer returns cached instances for values near zero, and creates new instances for bigger values. Optimizations can still be performed, but allocating a new instance will always take some time.


In response to comments, let me focus on what I took to be the key point of the question:

since we're dealing with a literal value, is it possible for the compiler to replace the primitive literal with a boxed literal

Yes, it is possible, but no, the Oracle javac compiler does not do this.

Does it matter? No, the performance hit for boxing to Boolean is infinitesimal; boxing boolean using the same valueOf() technique as other primitives is a safe and sane choice for the compiler.

Innumerable answered 8/1, 2016 at 23:31 Comment(3)
I would be surprised if the JIT weren't able to inline that and make both options essentially equivalent. Your first sentence is maybe too categorical...Hypodermis
@Hypodermis I would be surprised too, but would that happen on the first run? Even if it did, would that optimization process take extra time compared to code that used Boolean.TRUE instead of true?Innumerable
I think the key point is that the main performance hit arises whenever a new object must be allocated. In the case of Boolean.valueOf(), a new object is never allocated. The code really ought to make use of the class constant Boolean.TRUE, instead of the boolean primitive literal, but I would expect the actual performance difference between the two in this case to be immeasureably small,Hamsun

© 2022 - 2024 — McMap. All rights reserved.