简体   繁体   English

Java Double vs double:类类型与原始类型

[英]Java Double vs double: class type vs primitive type

I was curious to what the performance differences between Java's class and primitive type for double were. 我很好奇Java的类和double的原始类型之间的性能差异。 So I created a little benchmark and found the class type to be 3x-7x slower than the primitive type. 所以我创建了一个小基准测试,发现类类型比基本类型慢3x-7x。 (3x on local machine OSX, 7x on ideone) (在本地机器OSX上为3倍,在ideone上为7倍)

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 http://ideone.com/fDizDu

So why is the Double type so much slower? 那么为什么Double类型这么慢? Why is it even implemented to allow mathematical operators? 为什么甚至实现允许数学运算符?

So why is the Double type so much slower? 那么为什么Double类型这么慢?

Because the value is wrapped inside an object which needs allocation, deallocation, memory management plus getters and setters 因为该值包含在需要分配,释放,内存管理以及getter和setter的对象中

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. 因为autobox旨在允许你使用这样的包装器而不用担心它们不是普通的值。 Would you prefer not being able to have an ArrayList<Double> ? 你不希望没有ArrayList<Double>吗? Performance is not always necessary and a drop of 3x-7x of performance according to situations maybe acceptable. 性能并不总是必要的,根据情况可以接受3x-7x的性能下降。 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. 在每种情况下都是如此,使用LinkedList到随机访问元素可能有点过分但这并不意味着根本不应该实现LinkedList 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. 最后一点 :在对这些事情进行基准测试之前,你应该让VM热身。

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.) 你通常不会使用DoubleInteger等(偶尔Integer等可以用于存储'可选'值 - 你有时可能希望它为null 。这对于Double来说是不太可能的,因为NaN可用于那些。 )

The reason Double exists is as follows. Double存在的原因如下。 Java has two main types of value: objects (essentially like C/C++ pointers without the arithmetic), and primitive values (eg double ). Java有两种主要类型的值:对象(基本上类似于没有算术的C / C ++指针)和原始值(例如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. ArrayList这样的类可以被定义为接受任何Object ,它允许用户将StringFile或任何他们喜欢的东西存储在一个中 - 但是这样的定义不包括像double这样的原始值。 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. 所以像Double这样的类存在使得像ArrayList这样的类更容易存储double ,而不需要ArrayList的作者为所有基本类型创建特殊版本。

Double is a boxed double . Double是盒装double Thus in general the compiled code has to check the Double for null before doing anything with it. 因此,一般来说,编译后的代码必须在使用它之前检查Double for null。 This is of course slower than doing nothing. 这当然比什么都不做要慢。

Double (and other boxed versions of the primitives) is useful because it's an Object . Double (和其他盒装版本的基元)很有用,因为它是一个Object This allows you to pass it around to functions that would take an Object , and cast it back to Double somewhere else. 这允许您将其传递给将接受Object函数,并将其强制转换为其他位置的Double More usefully, it allows for generic types to contain it: A generic type cannot contain double or any other primitive, but it can contain a Double . 更有用的是,它允许泛型类型包含它:泛型类型不能包含double或任何其他原语,但它可以包含Double

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM