关于性能:Java Double vs double:类类型 vs 原始类型

Java Double vs double: class type vs primitive type

我很好奇 Java 的类和 double 的原始类型之间的性能差异是什么。所以我创建了一个小基准,发现类类型比原始类型慢 3 到 7 倍。 (本地机器 OSX 上 3x,ideone 上 7x)

这是测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

那么为什么 Double 类型会慢很多呢?为什么它甚至被实现为允许数学运算符?


So why is the Double type so much slower?

因为值被包裹在一个需要分配、释放、内存管理以及getter和setter的对象中

Why is it even implemented to allow mathematical operators?

因为 autobox 旨在允许您使用此类package器,而不必担心它们不是纯值这一事实。您是否希望不能拥有 ArrayList<Double>?性能并不总是必要的,根据情况将性能降低 3 到 7 倍是可以接受的。优化是一项并不总是存在的要求。

在任何情况下都是如此,使用 LinkedList 来随机访问元素可能是矫枉过正,但这并不意味着根本不应该实现 LinkedList。这也不意味着使用链表进行少量随机访问会严重影响性能。

最后一点:在对此类事物进行基准测试之前,您应该让 VM 预热。


您通常不会使用 DoubleInteger 等(有时 Integer 等对于存储"可选"值很有用 - 有时您可能希望它为 null . 这对于 Double 不太可能,因为 NaN 可用于那些。)

Double存在的原因如下。 Java 有两种主要的值类型:对象(本质上就像没有算术的 C/C 指针)和原始值(例如 Double)。像 ArrayList 这样的类可以定义为接受任何 Object,这允许用户将 StringFile 或他们喜欢的任何东西存储在一个中 - 但像 Double 这样的原始值不包含在这样的定义中。所以像 Double 这样的类的存在是为了让像 ArrayList 这样的类更容易存储 Double,而不需要 ArrayList 的作者为所有原始类型创建特殊版本。


Double 是一个装箱的 Double。因此,通常编译后的代码必须在对其进行任何操作之前检查 Double 是否为空。这当然比什么都不做要慢。

Double(和其他盒装版本的原语)很有用,因为它是一个 Object。这允许您将它传递给需要 Object 的函数,并将其转换回其他地方的 Double。更有用的是,它允许泛型类型包含它:泛型类型不能包含 Double 或任何其他原语,但它可以包含 Double.