106 votes

Map.clear() vs new Map : lequel sera le meilleur ?

J'ai une carte aussi syntaxique que Map<String, String> testMap = new HashMap<String, String>(); . Dans cette carte, il peut y avoir 1000 données.

Lorsque mon application requiert une nouvelle liste de données, je dois effacer la carte. Mais lorsque j'ai vu le code de Map.clear() comme étant

/**
     * Removes all of the mappings from this map.
     * The map will be empty after this call returns.
     */
    public void clear() {
        modCount++;
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            tab[i] = null;
        size = 0;
    }

Je me rends compte que la méthode claire tourne en boucle pendant n fois (où n est le nombre de données dans la carte). J'ai donc pensé qu'il pouvait y avoir un moyen de redéfinir cette Map en tant que testMap = new HashMap<String, String>(); et les cartes précédemment utilisées seront collectées à la poubelle.

Mais je ne suis pas sûr que ce soit une bonne solution. Je travaille sur une application mobile.

Pouvez-vous me guider ?

3 votes

Il y a longtemps que cette question a été postée, mais quoi qu'il en soit, Google continue de nous guider vers elle. Donc un autre avantage d'utiliser clear plutôt que new. Vous serez en mesure de déclarer la carte comme finale et ainsi le compilateur sera en mesure de détecter les bugs de programmation gratuitement. Pour d'autres types de structures, "final" supprimera également la charge de l'allocation d'une nouvelle mémoire, ce qui rendra notre code (beaucoup) plus rapide.

118voto

Vladimir Ivanov Points 23731

Question compliquée. Voyons ce qui se passe.

Vous instanciez une nouvelle instance, qui est soutenue par un nouveau tableau. Ainsi, le ramasseur d'ordures doit effacer toutes les clés et valeurs de la carte précédente, et effacer la référence à lui-même. Ainsi, l'algorithme O(n) est exécuté de toute façon, mais dans le fil du ramasseur d'ordures. Pour 1000 enregistrements, vous ne verrez pas de différence. MAIS. Les performances guide vous dit que il est toujours préférable de ne pas créer de nouveaux objets si vous le pouvez. Je choisirais donc clear() méthode.

Quoi qu'il en soit, essayez les deux variantes et essayez de mesurer. Mesurez toujours !

2 votes

+1 Après avoir lu le Guide, j'ai réalisé où j'étais confus. Merci.

2 votes

Voir mon commentaire à la réponse de @Tanveer. Vous ne pouvez pas estimer le coût du GC.

30voto

Tanveer Points 71

Quand vous dites Map.clear() sur une carte de taille n ... Vous demandez au CG de faire le ménage 2*n (Clé et valeur). Lorsque vous dites null à la même Carte, vous demandez au GC de nettoyer 2*n+1 (1 pour la carte elle-même) objets. Ensuite, vous devrez créer une nouvelle instance de carte, ce qui représente un coût supplémentaire. Optez donc pour Map.clear() . Il est conseillé de prédéfinir la taille de la carte lors de son instanciation.

3 votes

Les estimations du grand O que vous donnez ne s'appliquent que si les clés et les valeurs de la carte ne sont référencées nulle part ailleurs. Si des clés et des valeurs sont référencées ailleurs dans l'application, elles ne seront pas collectées. Je me trompe peut-être si par "nettoyage" vous voulez dire que le ramasseur d'ordures doit vérifier l'objet pour voir s'il doit être ramassé. Il y a un autre point ici... le ramasseur d'ordures peut jamais nettoyer les objets même s'il n'y a pas de référence à ceux-ci : stackoverflow.com/a/2506525/361855 . Ce que je veux dire, c'est qu'on ne peut pas estimer le coût du GC lorsqu'on change la carte réf.

10voto

sunriser Points 564

Je pensais que la création d'un objet en java était plus coûteuse en termes de mémoire, il est donc préférable d'opter pour .clear() Vous utilisez donc le même objet au lieu d'en créer un nouveau.

6voto

Suraj Chandran Points 12859

L'idée d'avoir la méthode clear() est de supprimer les références à d'autres objets de la carte, afin que les clés/valeurs ne soient pas retenues par le gcing si la "carte est référencée ailleurs".

Mais si votre carte est une carte locale utilisée uniquement par votre code spécifique (c'est-à-dire que la carte n'est pas référencée ailleurs), alors utilisez une nouvelle carte à la place, mais mettre 1000 références à null ne sera pas un gros problème de performance de toute façon.

1 votes

Oui. Ce ne sera pas un gros problème de performance pour 1000 références. Je demandais si la création d'une nouvelle instance est meilleure que la méthode claire ou non. Et y a-t-il un inconvénient à utiliser une nouvelle instance ?

1 votes

Le principal inconvénient est qu'avec new, votre ancienne HashMap est toujours en mémoire jusqu'à ce que le ramasseur de déchets la libère. Cela ajoutera un petit surcoût de mémoire et un peu plus de surcoût de traitement pour que le GC le libère. Dans tous les cas, les différences entre les deux options (réutilisation ou création d'un nouveau) seront négligeables (sauf si votre application ne fait que créer des HashMaps).

1voto

Pratik Points 15125

Le map.clear() qui supprimera toutes les données. Notez que cela ne supprimera que toutes les entrées, mais que le tableau interne utilisé pour stocker les entrées restera de la même taille (plutôt que d'être réduit à une capacité initiale). Si vous avez également besoin d'éliminer cela, le moyen le plus simple serait de supprimer la totalité du HashMap et de le remplacer par une nouvelle instance. Bien entendu, cela ne fonctionne que si vous contrôlez qui a un pointeur sur la carte.

Quant à la récupération de la mémoire, vous devrez laisser le ramasseur d'ordures faire son travail.

Vos valeurs sont-elles aussi longues ? Dans ce cas, vous pouvez envisager une implémentation plus efficace (en termes de mémoire) que le HashMap générique, comme le TLongLongHashMap que l'on trouve dans la bibliothèque de l'UE. Bibliothèque GNU Trove . Cela devrait permettre d'économiser beaucoup de mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X