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 类型会慢很多呢?为什么它甚至被实现为允许数学运算符?
- 由于需要装箱和拆箱,它很慢。这是预期的行为。
-
@HovercraftFullOfEels 这是有道理的,但似乎仍然有很多开销。
-
这是很多开销。因此,您应该避免在时间关键代码中使用原始package器类型。
-
多线程程序的成本更高。这是因为使用 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 预热。
您通常不会使用 Double、Integer 等(有时 Integer 等对于存储”可选”值很有用 – 有时您可能希望它为 null . 这对于 Double 不太可能,因为 NaN 可用于那些。)
Double存在的原因如下。 Java 有两种主要的值类型:对象(本质上就像没有算术的 C/C 指针)和原始值(例如 Double)。像 ArrayList 这样的类可以定义为接受任何 Object,这允许用户将 String、File 或他们喜欢的任何东西存储在一个中 – 但像 Double 这样的原始值不包含在这样的定义中。所以像 Double 这样的类的存在是为了让像 ArrayList 这样的类更容易存储 Double,而不需要 ArrayList 的作者为所有原始类型创建特殊版本。
Double 是一个装箱的 Double。因此,通常编译后的代码必须在对其进行任何操作之前检查 Double 是否为空。这当然比什么都不做要慢。
Double(和其他盒装版本的原语)很有用,因为它是一个 Object。这允许您将它传递给需要 Object 的函数,并将其转换回其他地方的 Double。更有用的是,它允许泛型类型包含它:泛型类型不能包含 Double 或任何其他原语,但它可以包含 Double.
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/267549.html