135 votes

Ce qui est la bibliothèque Java Collections plus efficace ?

Quel est le plus efficace Java Collections de la bibliothèque?

Il y A quelques années, j'ai fait beaucoup de Java et avait l'impression de retour alors que la mine est la meilleure (la plus efficace) de Java Collections de mise en œuvre. Mais quand je lis les réponses à la question "le Plus utile Java gratuit les bibliothèques?" J'ai remarqué que le trésor est à peine mentionnée. Afin de Java Collections de la bibliothèque est mieux maintenant?

Mise à JOUR: Pour clarifier, j'ai surtout envie de savoir ce que la bibliothèque à utiliser lorsque j'ai pour stocker des millions d'entrées dans une table de hachage etc. (besoin d'un petit moment de l'exécution et de la mémoire).

103voto

the.duckman Points 4796

La question est (maintenant) à propos de stocker beaucoup de données, qui peuvent être représentés à l'aide de primitives de type int, dans une Carte. Quelques réponses ici sont très trompeuses, à mon avis. Nous allons voir pourquoi.

J'ai modifié l'indice de référence du trésor pour les mesures d'exécution et la consommation de mémoire. J'ai aussi ajouté des PCJ à cette référence, qui est une autre des collections de la bibliothèque de types primitifs (j'ai utiliser beaucoup). Le "officiel" du trésor de référence ne permet pas de comparer IntIntMaps à Java de la Collection" Map<Integer, Integer>, probablement stocker Integers et stocker ints n'est pas la même chose d'un point de vue technique. Mais un utilisateur peut ne pas se soucier de cette technique en détail, il veut stocker des données qui peuvent être représentés avec ints efficacement.

D'abord la partie du code:

new Operation() {

     private long usedMem() {
        System.gc();
        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
     }

     // trove
     public void ours() {
        long mem = usedMem();
        TIntIntHashMap ours = new TIntIntHashMap(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           ours.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("trove " + mem + " bytes");
        ours.clear();
     }

     public void pcj() {
        long mem = usedMem();
        IntKeyIntMap map = new IntKeyIntOpenHashMap(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           map.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("pcj " + mem + " bytes");
        map.clear();
     }

     // java collections
     public void theirs() {
        long mem = usedMem();
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           map.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("java " + mem + " bytes");
        map.clear();
     }

Je suppose que les données proviennent primitive ints, ce qui semble sain d'esprit. Mais cela implique un temps d'exécution de la peine pour des java util, en raison de l'auto-boxing, ce qui n'est pas nécessaire pour le primitif collections de cadres.

Le moteur d'exécution de résultats (sans gc() des appels, bien sûr) sur WinXP, jdk1.6.0_10:

 100000 mettre opérations de 100000 contient des opérations 
java collections 1938 ms 203 ms
trove 234 ms 125 ms
pcj 516 ms 94 ms

Même si cela peut déjà sembler drastique, ce n'est pas la raison de l'utilisation d'un tel cadre.

La raison en est les performances de la mémoire. Les résultats pour une Carte contenant 100000 int entrées:

java collections oscille entre 6644536 et 7168840 octets
mine de 1853296 octets
pcj 1866112 octets

Java Collections besoins de plus de trois fois la mémoire par rapport à la collection primitive cadres. I. e. vous pouvez garder trois fois plus de données dans la mémoire, sans avoir recours à des e / s disque qui diminue les performances d'exécution par des grandeurs. Et c'est important. Lire highscalability pour savoir pourquoi.

Dans mon expérience forte consommation de la mémoire est le plus grand problème de performance avec Java, qui, bien sûr, les résultats dans le pire des performances d'exécution. Collection Primitive cadres peuvent vraiment aider ici.

Donc: Pas de java.util n'est pas la réponse. Et "ajouter des fonctionnalités" à la Java des collections n'est pas le point quand on parle d'efficacité. Aussi le moderne JDK collections ne sont pas "hors-même spécialisées de Trésors des collections".

Avertissement: La référence ici est loin d'être complète, il n'est ni parfait. Il est destiné à conduire à la maison le point, j'ai vécu dans de nombreux projets. Primitive collections sont utiles à tolérer de poisson API - si vous travaillez avec beaucoup de données.

72voto

Jon Skeet Points 692016

De l'inspection, il ressemble à la Mine est juste une bibliothèque de collections pour les types primitifs, il n'est pas comme c'est censé être l'ajout d'un lot de fonctionnalités par rapport à la normale des collections dans le JDK.

Personnellement (et je suis partial) j'aime Goyave (y compris l'ex-Google Java Collections de projet). Il fait diverses tâches (y compris les collections), beaucoup plus facile, d'une manière qui est au moins raisonnablement efficace. Étant donné que les opérations de collecte forment rarement un goulot d'étranglement dans mon code (dans mon expérience) c'est "mieux" que d'une des collections de l'API qui peut être plus efficace, mais ne faites pas mon code lisible.

Étant donné que le chevauchement entre le Trésor et la Goyave est à peu près nul, pourriez-vous préciser ce que vous cherchez à partir des collections de la bibliothèque.

45voto

smartnut007 Points 1728

Je sais que c'est un vieux post et il y a une tonne de réponses ici. Mais, Les réponses ci-dessus sont superficielles et plus simplifiée en termes de suggérant une bibliothèque. Il n'y a pas une bibliothèque qui fonctionne bien, à travers les différents points de repère présenté ici. La seule conclusion que je tire est si vous vous souciez de la performance et de la mémoire et en particulier de traiter avec des types primitifs, plus de peine de regarder les non jdk alternatives.

Ici, c'est un plus de son analyse, en termes de référence de la mécanique et des bibliothèques couvert. c'est un thread dans le mahout dev liste.

Les bibliothèques sont couverts

  • Des PROFESSIONS de
  • Trove
  • FastUtil
  • Cornac ( Colt )
  • Java Collections

Les résultats des trois repères Veuillez regarder le thread pour une description plus détaillée des trois Repères ici.

19voto

sstock Points 1289

Comme d'autres commentateurs l'ont remarqué, la définition de "efficace" jette un large filet. Cependant, personne n'a encore mentionné le Javolution de la bibliothèque.

Quelques points saillants:

  • Javolution classes sont rapides, très rapides (par ex. le Texte de l'insertion/suppression en O (Log(n)] au lieu de O[n] pour la norme StringBuffer/StringBuilder).
  • Tous les Javolution classes sont dur en temps réel conformes et ont hautement déterministe du comportement (en microsecondes). En outre (à la différence de la bibliothèque standard), Javolution est RTSJ sans danger (pas de mémoire de choc ou de fuite de mémoire lorsqu'il est utilisé avec Java extension Temps Réel).
  • Javolution la collecte en temps réel des classes (carte, liste, table et set) peut être utilisé à la place de la plupart des classes de collection et de fournir des fonctionnalités supplémentaires.
  • Le Javolution collections offrent la simultanéité des garanties de la mise en œuvre des algorithmes parallèles plus facile.

Le Javolution de distribution comprend une suite de test de sorte que vous pouvez voir comment ils se comparent à d'autres bibliothèques/les collections intégrées.

15voto

Alex Miller Points 28225

Certains de collecte des libs à prendre en compte:

Je voudrais d'abord et avant tout à atteindre pour le JDK collection de la bibliothèque. Il couvre la plupart des choses communes que vous devez faire, et c'est évidemment déjà disponible pour vous.

Google Collections est probablement la meilleure bibliothèque de haute qualité à l'extérieur de la JDK. Il est largement utilisé et bien pris en charge.

Apache Commons Collections des plus âgés et souffre un peu de la "too many cooks" problème, mais a beaucoup de choses utiles.

Trove a très collections spécialisées pour les cas comme primitive de clés/valeurs. Ces jours, nous constatons que sur moderne Jdk et avec Java 5+ collections et l'utilisation simultanée des cas, le JDK collections-même spécialisées de Trésors des collections.

Si vous avez vraiment haut de la simultanéité des cas d'utilisation, vous devriez certainement vérifier des trucs comme le NonBlockingHashMap dans le haut de l'échelle lib, qui est un sans verrouillage de la mise en œuvre et peut stomp sur ConcurrentHashMap si vous avez le droit de cas d'utilisation.

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