Quelle est la bibliothèque de collections Java la plus efficace?
Il y a quelques années, j'ai fait beaucoup de Java et j'avais l'impression à l'époque que le trésor est la meilleure implémentation (la plus efficace) des collections Java. Mais quand j'ai lu les réponses à la question « Les bibliothèques Java gratuites les plus utiles? », J'ai remarqué que le trésor est à peine mentionné. Alors, quelle bibliothèque Java Collections est la meilleure maintenant?
MISE À JOUR: Pour clarifier, je veux surtout savoir quelle bibliothèque utiliser lorsque je dois stocker des millions d'entrées dans une table de hachage, etc. (besoin d'un petit temps d'exécution et d'une petite empreinte mémoire).
java
collections
Franc
la source
la source
Réponses:
D'après l'inspection, il semble que Trove n'est qu'une bibliothèque de collections pour les types primitifs - ce n'est pas comme si elle était censée ajouter beaucoup de fonctionnalités par rapport aux collections normales du JDK.
Personnellement (et je suis partial) j'adore Guava (y compris l'ancien projet Google Java Collections). Cela facilite grandement diverses tâches (y compris les collections), d'une manière au moins raisonnablement efficace. Étant donné que les opérations de collecte forment rarement un goulot d'étranglement dans mon code (d'après mon expérience), c'est "mieux" qu'une API de collections qui peut être plus efficace mais ne rend pas mon code aussi lisible.
Étant donné que le chevauchement entre Trove et Guava est quasiment nul, vous pourriez peut-être clarifier ce que vous recherchez réellement dans une bibliothèque de collections.
la source
La question est (maintenant) de stocker beaucoup de données, qui peuvent être représentées à l'aide de types primitifs comme
int
, dans une carte. Certaines des réponses ici sont très trompeuses à mon avis. Voyons pourquoi.J'ai modifié le benchmark de trove pour mesurer à la fois le temps d'exécution et la consommation de mémoire. J'ai également ajouté PCJ à ce benchmark, qui est une autre bibliothèque de collections pour les types primitifs (je l'utilise beaucoup). Le benchmark «officiel» de trove ne compare pas IntIntMaps à Java Collection
Map<Integer, Integer>
, le stockageIntegers
et le stockageints
ne sont probablement pas les mêmes d'un point de vue technique. Mais un utilisateur peut ne pas se soucier de ce détail technique, il souhaite stocker des données représentables avecints
efficacité.D'abord la partie pertinente du code:
Je suppose que les données sont primitives
ints
, ce qui semble raisonnable. Mais cela implique une pénalité d'exécution pour java util, à cause de l'auto-boxing, qui n'est pas nécessaire pour les frameworks de collections primitives.Les résultats d'exécution (sans
gc()
appels, bien sûr) sur WinXP, jdk1.6.0_10:Bien que cela puisse déjà sembler drastique, ce n'est pas la raison d'utiliser un tel cadre.
La raison est la performance de la mémoire. Les résultats pour une carte contenant 100000
int
entrées:Les collections Java ont besoin de plus de trois fois la mémoire par rapport aux frameworks de collection primitifs. C'est-à-dire que vous pouvez conserver trois fois plus de données en mémoire, sans recourir aux E / S de disque, ce qui réduit considérablement les performances d'exécution. Et cela compte. Lisez la haute évolutivité pour découvrir pourquoi.
D'après mon expérience, la consommation de mémoire élevée est le plus gros problème de performances avec Java, ce qui entraîne bien sûr également une dégradation des performances d'exécution. Les frameworks de collection primitifs peuvent vraiment aider ici.
Donc: Non, java.util n'est pas la réponse. Et «l'ajout de fonctionnalités» aux collections Java n'est pas le but lorsque l'on se questionne sur l'efficacité. De plus, les collections JDK modernes ne " surpassent pas même les collections spécialisées Trove".
Avertissement: le benchmark ici est loin d'être complet, ni parfait. Il vise à faire ressortir le point que j'ai vécu dans de nombreux projets. Les collections primitives sont suffisamment utiles pour tolérer une API louche - si vous travaillez avec beaucoup de données.
la source
hashCode()
. Cela vous donne uneint
clé.Je sais que c'est un ancien message et il y a une tonne de réponses ici. Mais, les réponses ci-dessus sont superficielles et simplifiées en termes de suggestion d'une bibliothèque. Il n'y a pas de bibliothèque qui fonctionne bien à travers les divers benchmarks présentés ici. La seule conclusion que je tire est que si vous vous souciez des performances et de la mémoire et que vous vous occupez spécifiquement des types primitifs, cela vaut la peine de regarder les alternatives non jdk.
Voici une analyse plus solide, en termes de mécanique de référence et des bibliothèques couvertes. Ceci est un fil dans la liste des développeurs de mahout.
Les bibliothèques couvertes sont
Mise à jour juin 2015 : Malheureusement, les benchmarks d'origine ne sont plus disponibles et en plus c'est un peu obsolète. Voici un benchmark assez récent (janvier 2015) réalisé par quelqu'un d'autre. Il n'est pas aussi complet et ne dispose pas d'outils d'exploration interactifs que le lien d'origine.
la source
Comme d'autres commentateurs l'ont remarqué, la définition d '«efficace» jette un large filet. Cependant, personne n'a encore mentionné la bibliothèque Javolution .
Certains des points forts:
La distribution Javolution inclut une suite de benchmark afin que vous puissiez voir comment ils se comparent aux autres bibliothèques / collections intégrées.
la source
Quelques bibliothèques de collection à considérer:
Je voudrais avant tout atteindre la bibliothèque de la collection JDK. Il couvre les tâches les plus courantes que vous devez faire et est évidemment déjà disponible pour vous.
Google Collections est probablement la meilleure bibliothèque de haute qualité en dehors du JDK. Il est très utilisé et bien pris en charge.
Apache Commons Collections est plus ancienne et souffre un peu du problème du "trop de cuisiniers", mais contient également beaucoup de choses utiles.
Trove a des collections très spécialisées pour des cas comme les clés / valeurs primitives. Ces jours-ci, nous constatons que sur les JDK modernes et avec les collections Java 5+ et les cas d'utilisation simultanés, les collections JDK surpassent même les collections Trove spécialisées.
Si vous avez des cas d'utilisation de concurrence très élevée, vous devez absolument consulter des éléments tels que NonBlockingHashMap dans la bibliothèque à grande échelle, qui est une implémentation sans verrouillage et peut piétiner ConcurrentHashMap si vous avez le bon cas d'utilisation.
la source
java.util
Désolé pour la réponse évidente, mais pour la plupart des utilisations, les collections Java par défaut sont plus que suffisantes.
la source
Pour stocker des millions de dollars
String
sur une carte, consultez la page http://code.google.com/p/flatmapla source
Je suis développeur de happy-collections de happy-collections sur source-forge
la source
ConcurrentHashMap ainsi que le
java.util.concurrent
package doivent être mentionnés, si vous prévoyez d'utiliser le HashMap dans plusieurs threads. une faible empreinte mémoire est évaluée, car cela fait partie de java standard.la source
Cela dépend de la façon dont nous définissons «efficace».
Chaque structure de données a son propre comportement Big-Oh pour la lecture, l'écriture, l'itération, l'empreinte mémoire, etc. Une liste chaînée dans une bibliothèque est susceptible d'être la même que toute autre. Et une carte de hachage sera plus rapide pour lire O (1) qu'une liste chaînée O (n).
Cela ne semble pas être «le plus efficace». Cela me semble "le plus populaire".
Juste quelques commentaires - je n'en ai jamais entendu parler, et je ne connais personne qui l'ait utilisé. Les collections intégrées au JDK, Google ou Apache Commons me sont bien connues.
la source
Trove offre quelques avantages.
Cela dit, beaucoup a été fait pour améliorer les collections jdk depuis l'écriture de trove.
Ce sont les stratégies de hachage qui me plaisent cependant ... Google pour trove et lisez leur aperçu.
la source
Si vous souhaitez stocker des millions d'enregistrements dans une table de hachage, il est probable que vous rencontriez des problèmes de mémoire. Cela m'est arrivé lorsque j'ai essayé de créer une carte avec 2,3 millions d'objets String, par exemple. Je suis allé avec BerkeleyDB , qui est très mature et fonctionne bien. Ils ont une API Java qui encapsule l'API Collections, de sorte que vous pouvez facilement créer des cartes arbitrairement grandes avec très peu d'espace mémoire. L'accès sera cependant plus lent (car il est stocké sur disque).
Question complémentaire : existe-t-il une bibliothèque décente (et efficace), bien entretenue, pour les collections immuables? Clojure a un excellent support pour cela, et ce serait bien d'avoir quelque chose de similaire pour Java.
la source