web-dev-qa-db-fra.com

list.clear () vs list = new ArrayList <Integer> ();

Laquelle des 2 options est la meilleure et la plus rapide pour effacer une liste de tableaux, et pourquoi?

list.clear() 

ou

list = new ArrayList<Integer>();

Il arrive que je doive, à des moments aléatoires, effacer toutes les entrées de mon ArrayList et je n'ai aucun moyen de savoir combien il y aura de nouvelles entrées à l'avenir, il pourrait y avoir 0 ou un 1000. Quelle méthode est plus rapide et meilleure, et pourquoi?

117
Greg

Il est difficile de savoir sans repère, mais si vous avez beaucoup d'éléments dans votre ArrayList et que la taille moyenne est inférieure, il sera peut-être plus rapide de créer un nouvel ArrayList.

http://www.docjar.com/html/api/Java/util/ArrayList.Java.html

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}
71
dfb

List.clear enlèverait les éléments sans réduire la capacité de la liste.

groovy:000> mylist = [1,2,3,4,5,6,7,8,9,10,11,12]
===> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist.clear()
===> null
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist = new ArrayList();
===> []
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@2bfdff
groovy:000> mylist.elementData.length
===> 10

Ici, mylist a été effacé, les références aux éléments qu'il détient ont été annulées, mais il conserve le même tableau de sauvegarde. Puis mylist a été réinitialisé et a reçu un nouveau tableau de sauvegarde, l’ancien étant GCed. Donc, une façon de conserver la mémoire, l’autre la jette et elle est réaffectée à partir de zéro (avec la capacité par défaut). Ce qui est mieux dépend si vous voulez réduire le nombre de désabonnements de la récupération de place ou minimiser la quantité actuelle de mémoire inutilisée. Le fait de savoir si la liste reste assez longtemps pour pouvoir sortir d’Eden pourrait être un facteur déterminant quant à la vitesse la plus rapide (car cela pourrait rendre la collecte des déchets plus coûteuse).

23
Nathan Hughes

Je pense que la réponse est que cela dépend de toute une série de facteurs tels que:

  • si la taille de la liste peut être prédite à l'avance (c'est-à-dire pouvez-vous définir la capacité avec précision),
  • si la taille de la liste est variable (c'est-à-dire chaque fois qu'elle est remplie),
  • combien de temps la liste durera-t-elle dans les deux versions, et
  • vos paramètres de tas/GC et CPU.

Cela rend difficile de prédire lequel sera le meilleur. Mais mon intuition est que la différence ne sera pas si grande.

Deux conseils pour optimiser:

  • Ne pas perdre du temps essayer d’optimiser cela ... sauf si l’application est objectivement trop lente ET la mesure effectuée à l'aide d'un profileur vous indique qu'il s'agit d'un point chaud de performance. (Il est probable qu'une de ces conditions préalables ne sera pas vraie.)

  • Si vous décidez d'optimiser cela, faites-le scientifiquement. Essayez les deux (toutes) alternatives et choisissez la meilleure solution en mesurant les performances de votre application réelle sur un ensemble problème/charge de travail/entrée réaliste. (Un repère artificiel est susceptible de vous donner des réponses qui ne prédisent pas un comportement réel, à cause de facteurs comme ceux que j'ai énumérés précédemment.)

17
Stephen C

Le premier .clear(); gardera la même liste, effacez simplement la liste.

Le second new ArrayList<Integer>(); crée un nouveau ArrayList en mémoire.

Suggestion: d'abord parce que c'est ce qui est conçu pour le faire.

15
RMT

J'ai essayé le programme ci-dessous, avec l'approche à la fois. 1. En effaçant l’arraylist obj dans la boucle 2. en créant un nouveau New Arraylist dans la boucle.

List al= new ArrayList();
        for(int i=0;i<100;i++)
        {
            //List al= new ArrayList();

            for(int j=0;j<10;j++)
            {
                al.add(Integer.parseInt("" +j+i));
                //System.out.println("Obj val " +al.get(j));
            }
            //System.out.println("Hashcode : " + al.hashCode());
            al.clear();

        }

et à ma grande surprise. l'allocation de mémoire n'a pas beaucoup changé.

Avec l'approche New Arraylist.

Mémoire libre totale avant boucle: 64,909 ::

Mémoire libre totale après boucle: 64 775 ::

avec une approche claire,

Mémoire libre totale avant boucle: 64,909 :: Mémoire libre totale après boucle: 64 765 ::

Cela signifie donc qu’il n’ya pas beaucoup de différence dans l’utilisation de arraylist.clear du point de vue de l’utilisation de la mémoire.

5
vishal

S'il y a de bonnes chances que la liste contienne autant d'éléments que lors de son effacement, et si vous n'avez pas besoin de mémoire libre, effacer la liste est une meilleure option. Mais je suppose que cela n'a probablement pas d'importance. N'essayez pas d'optimiser avant d'avoir détecté un problème de performances et identifié son origine.

4
JB Nizet

list.clear() va conserver le même ArrayList mais la même allocation de mémoire. list = new ArrayList<int>(); va allouer une nouvelle mémoire à votre ArrayList.

La grande différence est que ArrayLists se développera dynamiquement à mesure que vous aurez besoin de plus d'espace. Par conséquent, si vous appelez list.clear(), vous aurez toujours potentiellement beaucoup de mémoire allouée pour un ArrayList qui pourrait ne pas être nécessaire.

Ceci dit, list.clear() sera plus rapide, mais si la mémoire est importante, vous pouvez allouer une nouvelle liste de tableaux.

2
J Lundberg

Je suggérerais d'utiliser list.clear () plutôt que d'allouer un nouvel objet. Lorsque vous appelez le mot-clé "nouveau", vous créez plus d'espace en mémoire. En réalité, peu importe. Je suppose que si vous connaissez la taille de la liste, il peut être judicieux de créer un nouvel espace, puis de spécifier la taille du tableau.

La vérité est que cela n’aura pas d’importance à moins de faire de la programmation scientifique. Dans ce cas, vous devez aller apprendre le C++.

1
Ryan Amos