J'ai trouvé qu'il y avait une implémentation d'un ensemble code> code> qui utilise des hachages (avec toutes les conséquences utiles, telles que O (1) pour http: //ontopia.wordpress .COM / 2009/09/23 / A-FASTER-et-PLUS-COMPACT-SET / P>
http://alias-i.com/ Lingpipe / Docs / API / COM / ALIASI / UTIL / COMPACTHASHSET.HTML P>
serait-il alors une bonne idée de cesser d'arrêter d'utiliser contient () code> etc.) prétendait être plus efficace que
java.util.hastryset code> dans tous les aspects: p>
java.util.hashashset code> complètement où que j'ai besoin d'un
java.util.set code> en faveur de
com. aliasi.Util.compAcastSet code>? p>
3 Réponses :
Cela dépend. P>
traitez-vous avec de très grands ensembles et de nombreux opérations d'insertion ou de lecture? Cette nouvelle mise en œuvre a réduit le temps pendant une demi-million d'opérations. C'est une grande amélioration, mais si vous ne faites que quelques milliers d'opérations ou une douzaine, cela se transforme rapidement en micro-optimisation. p>
Les tests affichés inséraient également un Si vous avez un cas d'utilisation qui profite de la modification de manière statistiquement significative, utilisez-le. p> long code> dans l'ensemble. Les performances pour l'utilisation des heures d'exécution et de la mémoire peuvent changer si vous stockez autre chose dans l'ensemble. p>
Option 1: Ne vous souciez pas fort>. Si vous regardez dans la mise en œuvre de Hashset Java, vous découvrez qu'il utilise simplement un hashmap en interne: qui est une implémentation rapide, toutefois, chaque entrée de définition a une référence à une valeur, qui n'est pas avait besoin. D'où la consommation de mémoire. Ma première option est de "ne pas s'en soucier", car j'espère qu'à l'avenir, quelqu'un fournira un hashset amélioré dans le JDK. Les ingénieurs logiciels doivent toujours avoir de l'espoir et une attitude positive :) p> dans la logique de programme normale, je m'envoie toujours aux normes fournies autant que possible et utilisez ce qui est disponible. Cela évite l'effet que chaque programmeur utilise sa propre "mise en oeuvre de choix préférée" ou, encore pire, fait une longue recherche quelle est la meilleure implémentation de hashset à utiliser;) p> Oracle a-t-il un billet de bug ouvert Pour le pauvre hashmap? Impossible de trouver une .... p> Option 2: Care Strong>. Si vous n'êtes pas sur la valeur logique des entreprises, mais dans un code de middleware technique, les performances peuvent compter. Ensuite, il existe différentes options.
La CompaceThashmap dans Google Guava est une. Une autre belle bibliothèque est la collections primitives haute performance . Dans HPPC, vous trouvez des ensembles pour chaque type primitif. Je pense que vous trouverez également d'autres choses qui correspondent à votre objectif particulier. Tous les remplaçants de HASHMAP peuvent avoir exactement la même sémantique que le haschmap orginal. P> Donc, je ne remplacer personnellement jamais Java.util.hashmap juste "par défaut". P> P>
Commençons un petit jeu de référence.
Les repères sont basés sur des repères de l'article original, mais utilisez des outils modernes. P>
Set implementation Speed Memory footprint Score Units +UCOops -UseCompressedOops CompactHashSet 828 ns/op 8.4 16.8 bytes/elem HashSet 676 ns/op 37.4 60.3 bytes/elem HPPC Set 853 ns/op 10.5 18.9 bytes/elem Koloboke Set 587 ns/op 8.4 16.8 bytes/elem GuavaCompactHashSet 874 ns/op 25.9 37.4 bytes/elem
Je ne comprends pas comment un CompacthacastSet code> peut être presque 4x inférieur à un
hashset code> lorsqu'il utilise des entrées liées de la même manière.
Je vois ... c'est un autre CompaCharasset code>, je voulais dire celui de Google.
@maaArtinus a mis à jour la réponse. Pour être honnête, je ne comprends pas pourquoi java.util.hashashset code> largement critiqué pour "lazy"
HASHMAP code> -Deleging implémentatif fonctionne si bien contre des implémentations spécialement optimisées. Peut-être qu'il y a une erreur dans les points de repère?
Merci pour la référence complète! Ma critique sur Java.Util.Hashashset était particulièrement en ce qui concerne l'efficacité de la mémoire.
1. Il y a des compromis. Vous pouvez utiliser un dense hashmap code> et le rendre plus petit et plus lent. 2. Vos données sont parfaitement aléatoires, ce qui peut favoriser certaines implémentations. 3. Votre "recherche" ne trouve difficilement rien, ce qui peut créer un biais aussi. 4. La même chose pour "supprimer". 5. En réalité, de nombreux points de repère différents seraient nécessaires pour obtenir une réponse complète (mais que pourrions-nous faire avec ce nombre de chiffres).
@cruftex the hashmap.enterry code> semble gaspillé pour un
hashset code>, mais sur un JVM 32 bits ou avec "compressressuops", le champ inutile
valeur code> est libre en raison de l'alignement.
COMPACTHASTSET Laisse la valeur
CODE> et
HASH CODE>, où ce dernier est utilisé dans le HM pour la vitesse (en évitant la comparaison de la clé).
Pourquoi ajouter une autre dépendance du pot à votre projet lorsque
hashset code> fonctionne parfaitement? Sauf si vous développez que vous développez des applications de latence faible et que vous savez i> que vous avez des problèmes de performance ou de mémoire tas
Avez-vous des problèmes de performance où vous utilisez des hashsets? Si c'est le cas, faites vos propres points de repère et voyez ce que c'est bon. Ensuite, vous pouvez décider si vous devez basculer ou non.
Votre premier lien montre une très bonne comparaison. Si
CompaceTharaseSet code> offre tout ce qu'un
hashset code> offre et peut-être plus, pourquoi pas simplement l'utiliser?
@ NJZK2 Je vois votre point et non, je n'ai pas encore de problèmes de performance avec hashset (au moins il n'y a pas de problème à ce que je suis au courant), mais si j'aurai rencontré ces problèmes et que je devrai utiliser la nouvelle mise en œuvre efficace de toute façon, Sera-t-il alors logique de se débarrasser de
hashset code> s dans mon code? Je veux dire, mis à part la performance, vous risquez d'utiliser une implémentation différente d'un ensemble qui pourrait potentiellement être nocif?
@MOHAMMAMMAD: Parce que depuis que les personnes encore moins utilisent, il est beaucoup plus enclin à contenir des bugs qui n'ont peut-être pas encore été découverts.
Si vous lisez les commentaires dans le premier lien, l'un des demandes d'utilisateurs Hashset est plus rapide pour leur cas d'utilisation. Longue histoire courte, il n'y a pas d'ensemble "le plus rapide". Vous devez choisir le bon pour votre cas d'utilisateur i> (basé sur le calendrier réel des scénarios du monde réel).
Intéressant que GUAVA dispose également d'une compacthacastSet si vous souhaitez inclure un pot supplémentaire qui fournit encore plus de fonctionnalités et sera plus largement utilisé par la communauté Java
Cela dépend vraiment de ce que vous optimisez; Cela va être un compromis, peu importe. Si vous n'avez pas I> Benchmarks réels i> pour prouver que l'un vaut mieux pour votre cas d'utilisation que l'autre, vous n'avez pas vraiment de raison pour vous attendre à ce que l'un soit préférable à un autre.
De plus, si vous lisez le deuxième lien, le CompaceThrasheSet est pas i> compatible avec le hashset. Entre autres choses, NULL ne peut pas être utilisée et vous pourriez obtenir des exceptions classiques de classe dans certains scénarios qui ne voudraient pas jeter pour Hashset.
@Brad Il est étrange que cette classe ait été écrite en 2012, j'utilise une version beaucoup plus récente de Guava et je n'ai pas entendu parler de cette classe, et d'ailleurs, ne l'avez pas dans mon pot de goyave (téléchargé d'un repo public. avec Maven) du tout.
@Susei: Si vous regardez le lien Brad, vous verrez qu'il relie directement à un changement qui a ajouté cette classe, et vous verrez mon nom comme l'auteur de changement. Nous n'exposons pas cette classe à Guava parce que les compromis sont complexes, et cela n'est pas évident même pour nous lorsque les différentes versions sont appropriées.