I was curious to what the performance differences between Java's class and primitive type for double were. So I created a little benchmark and found the class type to be 3x-7x slower than the primitive type. (3x on local machine OSX, 7x on ideone)
Here is the test:
class Main {
public static void main(String args[]) {
long bigDTime, littleDTime;
{
long start = System.nanoTime();
Double d = 0.0;
for (Double i = 0.0; i < 1432143.341; i += 0.1) {
d += i;
}
long end = System.nanoTime();
bigDTime = end - start;
System.out.println(bigDTime);
}
{
long start = System.nanoTime();
double d = 0.0;
for (double i = 0.0; i < 1432143.341; i += 0.1) {
d += i;
}
long end = System.nanoTime();
littleDTime = end - start;
System.out.println(littleDTime);
}
System.out.println("D/d = " + (bigDTime / littleDTime));
}
}
http://ideone.com/fDizDu
So why is the Double type so much slower? Why is it even implemented to allow mathematical operators?
int , float , double , long , short , boolean and char are examples of primitive data types. You can't invoke methods on these data types and they don't have a high memory footprint, which is their striking difference from classes. Everything else is a class (or class-like in the case of interfaces and enums).
Double is an object and double is a primitive data type. See this answer for more details. The Double class wraps a value of the primitive type double in an object. An object of type Double contains a single field whose type is double.
Data types are divided into two groups: Primitive data types - includes byte , short , int , long , float , double , boolean and char. Non-primitive data types - such as String , Arrays and Classes (you will learn more about these in a later chapter)
Primitives are passed by value, i.e. a copy of the primitive itself is passed. Whereas for objects, the copy of the reference is passed, not the object itself. Primitives are independent data types, i.e. there does not exist a hierarchy/super class for them. Whereas every Object is descendent of class "Object".
So why is the Double type so much slower?
Because the value is wrapped inside an object which needs allocation, deallocation, memory management plus getters and setters
Why is it even implemented to allow mathematical operators?
Because autobox is meant to allow you to use such wrappers without worrying about the fact that they are not plain values. Would you prefer not being able to have an ArrayList<Double>
? Performance is not always necessary and a drop of 3x-7x of performance according to situations maybe acceptable. Optimization is a requirement which is not always present.
This is true in every situation, using a LinkedList
to random access elements could be overkill but this doesn't mean that LinkedList
shouldn't be implemented at all. This neither means that using a linked list for few random accesses could interfere with performance so much.
A final note: you should let the VM warm up before benchmarking such things.
You wouldn't normally use Double
, Integer
, etc. (Occasionally Integer
etc. can be useful to store an 'optional' value - you might want it to be null
sometimes. This is less likely with Double
because NaN
is available for those.)
The reason Double
exists is as follows. Java has two main types of value: objects (essentially like C/C++ pointers without the arithmetic), and primitive values (e.g. double
). Classes like ArrayList
can be defined to accept any Object
, which allows users to store String
, File
or whatever they like in one - but primitive values like double
are not covered by such a definition. So classes like Double
exist to make it easier for classes like ArrayList
to store double
s, without requiring the authors of ArrayList
to create special versions for all the primitive types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With