web-dev-qa-db-fra.com

Java Double vs double: type de classe vs type primitif

J'étais curieux de savoir quelles étaient les différences de performances entre la classe Java et le type primitif pour double. J'ai donc créé un petit benchmark et trouvé que le type de classe était 3x-7x plus lent que le type primitif. (3x sur la machine locale OSX, 7x sur ideone)

Voici le 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/fDizD

Alors pourquoi le type Double est-il tellement plus lent? Pourquoi est-il même implémenté pour permettre aux opérateurs mathématiques?

17
Patrick Lorio

Alors pourquoi le type Double est-il tellement plus lent?

Parce que la valeur est enveloppée dans un objet qui nécessite une allocation, une désallocation, une gestion de la mémoire ainsi que des getters et setters

Pourquoi est-il même implémenté pour permettre aux opérateurs mathématiques?

Parce que la boîte automatique est destinée à vous permettre d'utiliser de tels wrappers sans vous soucier du fait qu'il ne s'agit pas de valeurs simples. Préféreriez-vous ne pas avoir de ArrayList<Double>? Les performances sont pas toujours nécessaires et une baisse de 3x-7x des performances selon les situations peut être acceptable. L'optimisation est une exigence qui n'est pas toujours présente.

Cela est vrai dans toutes les situations, l'utilisation d'un LinkedList pour des éléments d'accès aléatoire pourrait être exagéré mais cela ne signifie pas que LinkedList ne devrait pas du tout être implémenté. Cela ne signifie pas non plus que l'utilisation d'une liste chaînée pour quelques accès aléatoires pourrait nuire autant aux performances.

ne note finale: vous devriez laisser le VM s'échauffer avant de comparer de telles choses.

22
Jack

Vous n'utiliseriez normalement pas Double, Integer, etc. (Parfois, Integer etc. peut être utile pour stocker une valeur "facultative" - ​​vous voudrez peut-être qu'elle soit null parfois. C'est moins probable avec Double car NaN est disponible pour ceux-ci.)

La raison pour laquelle Double existe est la suivante. Java a deux principaux types de valeur: les objets (essentiellement comme les pointeurs C/C++ sans l'arithmétique) et les valeurs primitives (par exemple double). Les classes comme ArrayList peut être défini pour accepter n'importe quel Object, ce qui permet aux utilisateurs de stocker String, File ou tout ce qu'ils veulent en un - mais les valeurs primitives comme double sont non couvert par une telle définition. Ainsi, des classes comme Double existent pour faciliter le stockage de ArrayLists par des classes comme double, sans exiger les auteurs de ArrayList pour créer des versions spéciales pour tous les types primitifs.

8
entheh

Double est un double encadré. Ainsi, en général, le code compilé doit vérifier le Double pour null avant de faire quoi que ce soit avec lui. C'est bien sûr plus lent que de ne rien faire.

Double (et d'autres versions encadrées des primitives) est utile car c'est un Object. Cela vous permet de le transmettre aux fonctions qui prendraient un Object, et de le restituer à Double ailleurs. Plus utilement, il permet aux types génériques de le contenir: Un type générique ne peut pas contenir double ou toute autre primitive, mais il peut contenir un Double.

4
user2201345