user1796942
user1796942

Reputation: 3528

Java: How much slower would it be if I used primitive data types boxed in classes?

I am translating C++ code and there is a lot of use of typedef. I can't do that in Java, so what I do instead is:

// C++
typedef unsigned int BucketKey; 


// Java
public class BucketKey {
    public int val;
}

I am not a Java expert, actually new in here, and I was wondering how expensive will it be to use BucketKey, instead of just using int directly?

Just to mention, I need to do this for at least 5 more types.

THanks

Upvotes: 0

Views: 413

Answers (6)

Edmondo
Edmondo

Reputation: 20080

Please note that your question has nothing to do with boxing: a java int is a primitive type, its boxed version is java.lang.Integer. You are questioning whether access to a class member is slower than access to a primitive variable. Most of Java performance question have basically no answer: there is a difference, but that difference depends on a number of factors including:

  • Hardware Architecture
  • Java version
  • Operating system

However, unless you are doing high-frequency trading, the performance impact will be a perfectly acceptable downside compared to the tremendous increase in productivity if you correctly structure your program respecting encapsulation.


If you really have such performance problems and you consider working on the JVM, you should look to more modern programming languages than Java.

The truth is that JVM has no support for Value classes. However, Scala has:

http://docs.scala-lang.org/overviews/core/value-classes.html

Upvotes: 2

Blessed Geek
Blessed Geek

Reputation: 21644

There are legitimate requirements to using boxing classes.

For example, using a box rather than the primitive in an argument allows JAX-B to avoid including an attribute in an XML element if the argument is null. That is to prevent

<employee name='Henry' id=null years=null />

but which should be

<employee name='Henry' />

Therefore, if such a requirement arises, might as well use the boxed instance.

I have no expertise in the Java compiler, but I would expect the compiler to have taken care of the optimisation. My mental-experiments seem to say that such would be an expected and relatively simple optimisation.

My idea is, provided that the Java compiler would optimise boxing anyway, at some point you would need to take the hit of instantiating the boxed instance anyway. Why not do it early and enjoy all its features and facilities?

Upvotes: 0

Dhruv Gairola
Dhruv Gairola

Reputation: 9182

Go with the primitive int if possible. The penalty for boxing/unboxing is not high, but you should benchmark this to be sure. It doesn't look like you're boxing/unboxing in your example in any case. You're making a primitive vs object decision.

Anyway, you shouldn't worry too much about this unless you're making a real time system or something like that.

I agree with Peter Lawrey. Use visual vm to identify bottlenecks. I've written a short tutorial on this too [source].

Upvotes: 1

Csq
Csq

Reputation: 5855

It adds a HUGE overhead, especially if you have arrays. I'd recommend writing a test program to compare.

In Java int[100] creates an array with 100 ints - similar to C/C++, Integer[100] or YourObjectContainingAnIntMember[100] has an array with 100 references (pointers) to 100 distinct objects.

Not to mention that BucketKey object will have reference semantics but int has value semantics like in C++:

BucketKey x = new BucketKey(100);
BucketKey y = x
y.value = 200; // x will change as well

int x = 100;
int y = x;
y = 200; // x will remain 100

It's also worth adding that the typedef in C++ does not create a new type either. So the type of BucketKey variables are simply ints - but Java has no typedef to call an int more ways. The C++ solution with different type would be

struct BucketKey {
    value x;
}

Upvotes: 3

Peter Lawrey
Peter Lawrey

Reputation: 533492

The difference it makes depends on how much you are using it. If you are using it one million time per second. It won't make much difference. If you are using it 10 million times a second you will notice it and if you are using it 100 million times a second a primitive will be many times faster.

You should write a simple, clear working program and only then profiler it it (e.g. with VisualVM) to find the bottlenecks. It is more than likely that your bottlenecks will be some where you wouldn't have predicted.

Upvotes: 1

Eric J.
Eric J.

Reputation: 150108

There is a little overhead boxing and unboxing values. Having said that, the overhead is usually negligible compared to the rest of the processing in a "typical" program.

I would suggest constructing a test with your worst-case (in terms of number of key access) use case and measure the performance both ways if you see some value to having a flexible key type.

If you do not need the flexibility to change the key type as a practical matter, just go with int.

Upvotes: 0

Related Questions