Does boxing cause performance issues?
Asked Answered
M

4

5

I'm working on a project in which we are producing a language which compiles to java. The framework we are using (xtext) makes prolific use of boxing in its generated code. Specifically, if you have a statement like:

int i = 1;
int j = 2;
int k = i + j;

Then the compiled code looks like:

IntegerExtensions.operator_plus(((Integer)i), ((Integer)j))

Now, in the project I'm working on, there are certain situations where particular basic binary operations are going to be extremely common (especially increments and comparisons).

My question is: is this going to be a problem in terms of performance, or will JIT (or similarly intelligent JVM features) simply realize what's going on and fix it all?

PLEASE READ BEFORE POSTING: I'm not interested in getting responses saying "you shouldn't care, make it readable". This code is generated, and I simply don't care about the readability of the generated code. What I do care about is that we don't take a significant performance hit from this.

Thanks

Mook answered 11/12, 2011 at 23:9 Comment(5)
When you say compiled code, do you mean compiled into your framework or compiled into bytecode?Hammering
Boxing is more expensive than not boxing. Does it matter? (This is the only real question here.) Well, "it depends"... also, why does the compiled code look like that? :) There is an iadd native java bytecode...Lucinalucinda
@glowcodeer: When I say compiled code, I mean taken from my language and compiled into .java files.Mook
@pst: I'm not sure why the code looks like that, but I'm assuming there's some kind of reason behind it in the general case. As for "Does it matter?", that's not actually the question - the question is "is it always more expensive?" - see what I mentioned about just-in-time compiling, and my comment on John's answer.Mook
@Mook The specific answer is still: "likely yes" and the general answer is "it depends". Just because a new object is not necessarily created doesn't not mean it has the same paths in bytecode or JIT'ed code. Finding a pathologically ideal case of where it is JIT'ed away effectively -- assuming such a case exists -- does not help. Only a performance analysis replicating the real usage is capable of "correctly" answering this question.Lucinalucinda
B
4

This can in fact have an impact. When the cast to Integer occurs it will convert the int to Integer using Integer.valueOf(int n) method. This method will check to see if the value is within the cache range (-128 to 127) and if it is not it will create new Integer(n)

The amount of an impact may be a lot or little, you would have to test yourself.

Balmung answered 11/12, 2011 at 23:16 Comment(3)
So there's no chance that JIT or something like it might just realise that the boxing is totally pointless and get rid of it completely? These boxes happen very very frequently, under essentially the same situations, and don't hang around very long, and I was really hoping that the JVM might be able to do my job for me.Mook
To my knowledge, JIT will not bypass the boxing operation (that would be one heck of a runtime optimization algorithm if it could).Goddord
With -XX:+EscapeAnalysis it is possible to drop the created auto-boxed object. In reality, I have never seen the Sun/Oracle JVM drop the object creation. Its much more useful to start by profiling your application to determine whether it matters before worrying about it.Erlineerlinna
T
3

To say that it causes performance issues is dependent on what you'd call an issue. And what you'll call an issue is probably dependent on what kind of problems the code will be solving.

There's a section in this answer that sums it up, and also provides a link to the Autoboxing guide, which mentions:

It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code.

And here's a specific example with benchmarks focusing on int/Integer autoboxing

Simple question: How expensive is autoboxing of int/Integer types?

Simple answer: 15 nanoseconds per boxing.

Thea answered 11/12, 2011 at 23:15 Comment(0)
R
3

A few observations from my experience:

  1. Boxing in general does decrease the performance of an application. How noticeable it is depends on the nature of the implemented algorithms. Whether it's worth fixing and where is something only a profiler and your expected cost-to-benefit ratio can tell you.

  2. Boxing in general does increase the memory usage of an application. This, as far as I am concerned, is very important - probably more important than performance.

    An int in Java takes up 4 to 8 bytes (depending on the JVM implementation) of memory for 32 bits of range. An Integer will take up 20 to 24 bytes on an 64-bit system - and you still need a reference to it. For an application that processes large arrays that could easily quadruple (x4) its memory requirements - or worse.

    In this case, boxing can make the difference between "It works" and "It does not work" - there is only so much memory you can have on a given computer. Performance does not even come into the discussion, although, memory-starved applications will generally be slower as well.

That said, objects do have a useful advantage: there is a native way to say "no value exists" by using null.

Record answered 11/12, 2011 at 23:40 Comment(1)
I suppose that, although memory could be an issue, the GC should be able to cope with this. The situation I'm dealing with has objects boxed for very short amounts of time, so GC should be able to discard the produced objects very quickly. The persisted state is still kept as an int, it's only when something needs to happen that it gets boxed.Mook
S
1

Simply put: test it.

Make the two versions of a simple example and measure the time it takes. Then you'll know the exact difference in performances and if you can afford it.

Saucedo answered 11/12, 2011 at 23:15 Comment(1)
Yes. We should google and test everything ourselves. We don't need no stinking questions at SO.Tananarive

© 2022 - 2024 — McMap. All rights reserved.