Java Double vs double: tipo de class versus tipo primitivo

Eu estava curioso para saber quais eram as diferenças de desempenho entre a class Java e o tipo primitivo para double. Então eu criei um pequeno benchmark e achei o tipo de class 3x-7x mais lento que o tipo primitivo. (3x na máquina local OSX, 7x no ideone)

Aqui está o teste:

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

Então, por que o tipo Double é muito mais lento? Por que é mesmo implementado para permitir operadores matemáticos?

Então, por que o tipo Double é muito mais lento?

Porque o valor é empacotado dentro de um object que precisa de alocação, desalocação, gerenciamento de memory mais getters e setters

Por que é mesmo implementado para permitir operadores matemáticos?

Porque autobox é destinado a permitir que você use esses wrappers sem se preocupar com o fato de que eles não são valores simples. Você prefere não ter uma ArrayList ? O desempenho nem sempre é necessário e uma queda de 3x-7x de desempenho de acordo com as situações pode ser aceitável. A otimização é um requisito que nem sempre está presente.

Isto é verdade em todas as situações, usando um LinkedList para elementos de access random poderia ser um exagero, mas isso não significa que LinkedList não deve ser implementado em tudo. Isso não significa que usar uma linked list para poucos accesss randoms pode interferir tanto no desempenho.

Uma nota final : você deve deixar a VM se aquecer antes de comparar essas coisas.

Você normalmente não usaria Double , Integer , etc. (Ocasionalmente Integer etc. pode ser útil para armazenar um valor ‘opcional’ – você pode querer que ele seja null às vezes. Isso é menos provável com Double porque NaN está disponível para eles. )

A razão pela qual o Double existe é a seguinte. Java tem dois tipos principais de valor: objects (essencialmente como pointers C / C ++ sem aritmética) e valores primitivos (por exemplo, double ). Classes como ArrayList podem ser definidas para aceitar qualquer Object , que permite aos usuários armazenar String , File ou o que quiserem em um – mas valores primitivos como double não são cobertos por tal definição. Portanto, classs como Double existem para tornar mais fácil para classs como ArrayList armazenar double s, sem exigir que os autores de ArrayList criem versões especiais para todos os tipos primitivos.

Double é uma checkbox double . Assim, em geral, o código compilado deve verificar o Double para null antes de fazer qualquer coisa com ele. Isso é mais lento do que não fazer nada.

Double (e outras versões em checkbox das primitivas) é útil porque é um Object . Isso permite que você passe para funções que levariam um Object e o convertem de volta para o Double em outro lugar. Mais útil, permite que tipos genéricos o contenham: um tipo genérico não pode conter o double ou qualquer outro primitivo, mas pode conter um Double .