[Lire Java efficace] Chapitre 2 Item 5 "Eviter la création d'objets inutiles"

Évitez de créer des objets inutiles

Comme le dit le titre. La création d'objets par inadvertance entraîne de mauvaises performances. Imaginons un peu et écrivons-le pour ne pas générer d'objets inutiles.

Glossaire

Boxe automatique

En Java, il existe deux types: le type primitif (type de base) et le type de référence. Les types primitifs, tels que int, ne peuvent pas être placés dans une collection. Les valeurs primitives doivent être "encadrées" dans la classe wrapper appropriée (Integer pour int), car la collection ne peut contenir que des références d'objet. Lorsque vous récupérez un objet de la collection, vous obtenez le Integer stocké. Si vous avez besoin d'un int, vous devez le «déballer» de l'entier en utilisant la méthode intValue. Étant donné que l'implémentation explicite de ceci est une source de complexité, Java dispose de fonctionnalités de boxing et de déballage automatiques. Boîte automatique pour la conversion automatique du type primitif à la classe wrapper La conversion automatique de la classe wrapper au type primitif est appelée unboxing.

Type primitif Classe de wrapper
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

Immuable

Un objet dont l'état ne peut pas être modifié après sa création.

Exemple de code

Ce code crée une nouvelle instance String à chaque fois que cette partie est exécutée.

Exemple 1


String s = new String("stringette");  //Ne fais pas ça

C'est acceptable

Exemple 2


String s = "stringette";  

Prenons, par exemple, la classe Person avec la méthode isBabyBoomer qui détermine si une personne est une génération du baby-boom. Dans la manière d'écrire ↓, chaque fois que la méthode isBabyBoomer est appelée, une nouvelle instance Calender, TimeZone, boomStart et boomEnd Date sont créées inutilement. Ne fais pas ça.

Exemple 3


public class Person {
    private final Date birthDate;

    //Omettre les autres champs, méthodes et constructeurs
    
    //Ne fais pas ça!
    public boolean isBabyBoomer() {
        //Génération inutile d'objets coûteux
        Calender gmtCal = 
            Calender.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
        return birthDate.compareTo(boomStart) >= 0 &&
               birthDate.compareTo(boomEnd)   <  0 ;     
    }
}

L'exemple 4 a amélioré les mauvais points de l'exemple 3. Lorsque la classe est initialisée, les instances Calender, TimeZone, BoomStart et BoomEnd Date ne sont créées qu'une seule fois. Cela peut améliorer considérablement les performances si la méthode isBabyBoomer est appelée fréquemment.

Exemple 4


public class Person {
    private final Date birthDate;

    //Omettre les autres champs, méthodes et constructeurs

    /**
     *Les dates de début et de fin du baby-boom.
     */
    private static final Date BOOM_START;
    private static final Date BOOM_END;

    static {
        Calender gmtCal =
            Calender.getInstance(TimeZone.getTimeZone("GMT");
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        BoomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        BoomEnd = gmtCal.getTime();
    }

    public boolean osBabyBoomer() {
        return birthDate.compareTo(BoomStart) >= 0 &&
               birthDate.compareTo(BoomEnd)   <  0 ;    
    }
}

L'exemple 5 est assez lent en raison d'une faute de frappe d'une lettre. La variable sum est déclarée comme Long au lieu de long. En conséquence, le programme crée environ 2 ^ 31 instances Long inutiles. (Chaque fois que vous ajoutez un i long à une somme longue, une instance augmente)

Leçon: choisissez un type de données de base sur un type de données de base en boîte et méfiez-vous de la boxe automatique involontaire

Exemple 5


//Un programme terriblement lent! Pouvez-vous signaler la création d'objet?
public static void main(String[] args) {
    Long sum = OL;
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}

Continuer

[Lire Java efficace] Chapitre 2 Item 6 "Supprimer les références d'objets obsolètes" https://qiita.com/Natsukii/items/5f2edd6a9bcdb94b03e5

Recommended Posts

[Lire Java efficace] Chapitre 2 Item 5 "Eviter la création d'objets inutiles"
[Lire Java efficace] Chapitre 2 Item 7 "Eviter les finaliseurs"
[Lire Java efficace] Chapitre 3 Point 12 "Considérer l'implémentation de Comparable"
[Java efficace] Évitez de créer des objets inutiles
[Lire Java efficace] Chapitre 2 Item 1 "Considérez les méthodes de fabrique statiques plutôt que les constructeurs"
[Lire Java efficace] Chapitre 2 Item 6 "Supprimer les références d'objets obsolètes"
[Lire Java efficace] Chapitre 2 Item 4 "Forcer l'impossibilité d'immobilisation avec un constructeur privé"
[Lire Java effectif] Chapitre 3 Rubrique 9 "Lors de la substitution d'égaux, toujours remplacer hashCode"
Point 71: éviter l'utilisation inutile d'exceptions vérifiées
Mesurez facilement la taille des objets Java
[Lire le Java efficace] Chapitre 2 Item 2 "Considérez un constructeur face à un grand nombre de paramètres de constructeur"
Efficace Java Chapitre 2
Effective Java Chapitre 6 34-35
Effective Java Chapitre 4 15-22
Java efficace Chapitre 3
Effective Java 3rd Edition Chapitre 2 Création et disparition d'objets
[Lire Java efficace] Chapitre 2 Item 3 "Forcer les caractéristiques de singleton avec un constructeur privé ou un type enum"
Efficace Java 3rd Edition Chapitre 3 Méthodes communes à tous les objets
[Java] Création d'annotations originales
Lire les 4 premiers octets du fichier de classe Java et générer CAFEBABE
[Java] Supprimer les éléments de la liste
[Édition Java] Histoire de la sérialisation
J'ai lu la source de ArrayList que j'ai lu
Trier la liste des objets Java
J'ai lu la source d'Integer
Efficacité de Java 3rd Edition Chapitre 5 Génériques
J'ai lu la source de Long
Méthodes efficaces du chapitre 8 de Java 3rd Edition
J'ai lu la source de Short
J'ai lu la source de Byte
L'origine des expressions Java lambda