¿Cuál es la biblioteca de colecciones de Java más eficiente?
Hace unos años, hice un montón de Java y tuve la impresión de que tesoro es la mejor (más eficiente) implementación de Colecciones de Java. Pero cuando leí las respuestas a la pregunta: " La mayoría de las bibliotecas Java libres útiles? " Noté que tesoro apenas se menciona. Entonces, ¿qué biblioteca de colecciones de Java es mejor ahora?
ACTUALIZACIÓN: para aclarar, en su mayoría quiero saber qué biblioteca usar cuando tengo que almacenar millones de entradas en una tabla hash, etc. (necesito un tiempo de ejecución pequeño y huella de memoria).
java
collections
Franco
fuente
fuente
Respuestas:
Después de la inspección, parece que Trove es solo una biblioteca de colecciones para tipos primitivos; no es como si estuviera agregando mucha funcionalidad sobre las colecciones normales en el JDK.
Personalmente (y soy parcial), me encanta la guayaba (incluido el antiguo proyecto Google Java Collections). Hace que las tareas (incluidas las colecciones) sean mucho más fáciles, de una manera que sea al menos razonablemente eficiente. Dado que las operaciones de recopilación rara vez forman un cuello de botella en mi código (en mi experiencia) esto es "mejor" que una API de recopilación que puede ser más eficiente pero no hace que mi código sea legible.
Dado que la superposición entre Trove y Guava es prácticamente nula, tal vez podría aclarar lo que realmente está buscando en una biblioteca de colecciones.
fuente
La pregunta es (ahora) sobre el almacenamiento de muchos datos, que se pueden representar usando tipos primitivos como
int
, en un Mapa. Algunas de las respuestas aquí son muy engañosas en mi opinión. A ver por qué.Modifiqué el punto de referencia de tesoro para medir tanto el tiempo de ejecución como el consumo de memoria. También agregué PCJ a este punto de referencia, que es otra biblioteca de colecciones para tipos primitivos (lo uso ampliamente). El punto de referencia del tesoro 'oficial' no compara IntIntMaps con los de la Colección Java
Map<Integer, Integer>
, probablemente almacenarIntegers
y almacenarints
no es lo mismo desde un punto de vista técnico. Pero a un usuario puede no importarle este detalle técnico, quiere almacenar datos representables de maneraints
eficiente.Primero la parte relevante del código:
Supongo que los datos son primitivos
ints
, lo que parece cuerdo. Pero esto implica una penalización de tiempo de ejecución para java util, debido al auto-boxeo, que no es necesario para los marcos de colecciones primitivas.Los resultados de tiempo de ejecución (sin
gc()
llamadas, por supuesto) en WinXP, jdk1.6.0_10:Si bien esto puede parecer drástico, esta no es la razón para usar dicho marco.
La razón es el rendimiento de la memoria. Los resultados para un mapa que contiene 100000
int
entradas:Java Collections necesita más de tres veces la memoria en comparación con los marcos de colección primitivos. Es decir, puede mantener tres veces más datos en la memoria, sin recurrir al disco IO que reduce el rendimiento del tiempo de ejecución por magnitud. Y esto importa. Lea la escalabilidad alta para descubrir por qué.
En mi experiencia, el alto consumo de memoria es el mayor problema de rendimiento con Java, que por supuesto también resulta en un peor rendimiento en tiempo de ejecución. Los marcos de colección primitivos realmente pueden ayudar aquí.
Entonces: No, java.util no es la respuesta. Y "agregar funcionalidad" a las colecciones de Java no es el punto cuando se pregunta sobre la eficiencia. Además, las colecciones modernas de JDK no "superan incluso a las colecciones especializadas de Trove".
Descargo de responsabilidad: el punto de referencia aquí está lejos de ser completo, ni es perfecto. Está destinado a llevar a casa el punto, que he experimentado en muchos proyectos. Las colecciones primitivas son lo suficientemente útiles como para tolerar la API sospechosa, si trabaja con muchos datos.
fuente
hashCode()
. Te da unaint
clave.Sé que esta es una publicación antigua y hay un montón de respuestas aquí. Pero, las respuestas anteriores son superficiales y demasiado simplificadas en términos de sugerir una biblioteca. No hay una biblioteca única que funcione bien en los diversos puntos de referencia presentados aquí. La única conclusión que obtengo es que si te importa el rendimiento y la memoria y específicamente tratar con tipos primitivos, vale la pena mirar las alternativas no jdk.
Aquí hay un análisis más sólido, en términos de mecánica de referencia y las bibliotecas cubiertas. Este es un hilo en la lista de desarrolladores de mahout.
Las bibliotecas cubiertas son
Actualización de junio de 2015 : Desafortunadamente, los puntos de referencia originales ya no están disponibles y además están un poco desactualizados. Aquí hay un punto de referencia bastante reciente (enero de 2015) realizado por otra persona. No es tan completo ni tiene las herramientas exploratorias interactivas como el enlace original.
fuente
Como han notado otros comentaristas, la definición de "eficiente" arroja una amplia red. Sin embargo, nadie ha mencionado aún la biblioteca Javolution .
Algunos de los aspectos más destacados:
La distribución de Javolution incluye un conjunto de pruebas de referencia para que pueda ver cómo se comparan con otras bibliotecas / colecciones incorporadas.
fuente
Algunas bibliotecas de colección a tener en cuenta:
En primer lugar, buscaría la biblioteca de la colección JDK. Cubre las cosas más comunes que debe hacer y, obviamente, ya está disponible para usted.
Google Collections es probablemente la mejor biblioteca de alta calidad fuera del JDK. Es muy utilizado y bien soportado.
Apache Commons Collections es más antiguo y sufre un poco del problema de "demasiados cocineros", pero también tiene muchas cosas útiles.
Trove tiene colecciones muy especializadas para casos como claves / valores primitivos. En estos días encontramos que en los JDK modernos y con las colecciones Java 5+ y los casos de uso concurrente, las colecciones JDK superan incluso a las colecciones especializadas de Trove.
Si tiene casos de uso de concurrencia realmente alta, definitivamente debería consultar cosas como NonBlockingHashMap en la biblioteca de gran escala, que es una implementación sin bloqueo y puede pisotear ConcurrentHashMap si tiene el caso de uso adecuado para ello.
fuente
java.util
Perdón por la respuesta obvia, pero para la mayoría de los usos, las colecciones de Java predeterminadas son más que suficientes.
fuente
Para almacenar millones
String
en un mapa, visite http://code.google.com/p/flatmapfuente
Soy desarrollador de happy-collections de happy-collections en source-forge
fuente
java.util.concurrent
Deben mencionarse ConcurrentHashMap y el paquete, si planea usar HashMap en varios subprocesos. Se asume una pequeña huella de memoria, ya que esto es parte de Java estándar.fuente
Depende de cómo definimos "eficiente".
Cada estructura de datos tiene su propio comportamiento Big-Oh para leer, escribir, iterar, huella de memoria, etc. Es probable que una lista vinculada en una biblioteca sea la misma que en cualquier otra. Y un mapa hash será más rápido para leer O (1) que una lista vinculada O (n).
Esto no suena como "más eficiente". A mí me parece el "más popular".
Solo algunos comentarios: nunca he oído hablar de él, y no conozco a nadie que lo haya usado. Las colecciones integradas en JDK, Google o Apache Commons son conocidas por mí.
fuente
Trove ofrece algunas ventajas.
Dicho esto, se ha hecho mucho para mejorar las colecciones jdk desde que se escribió tesoro.
Sin embargo, son las estrategias de hash lo que me hacen atractivo ... Google para buscar y leer su resumen.
fuente
Si desea almacenar millones de registros en una tabla hash, es probable que tenga problemas de memoria. Esto me sucedió cuando intenté crear un mapa con 2,3 millones de objetos String, por ejemplo. Fui con BerkeleyDB , que es muy maduro y funciona bien. Tienen una API de Java que envuelve la API de Colecciones, por lo que puede crear fácilmente mapas arbitrariamente grandes con muy poca huella de memoria. Sin embargo, el acceso será más lento (ya que está almacenado en el disco).
Pregunta de seguimiento : ¿existe una biblioteca decente (y eficiente), bien mantenida, para colecciones inmutables? Clojure tiene un excelente soporte para esto, y sería bueno tener algo similar para Java.
fuente