2010-05-20 9 views
6

Estoy buscando una buena implementación del mapa hash. Específicamente, uno que es bueno para crear una gran cantidad de mapas, la mayoría de ellos pequeños. Entonces la memoria es un problema. Debe ser seguro para la ejecución de subprocesos (aunque perder el put impar puede ser un compromiso aceptable a cambio de un mejor rendimiento), y rápido tanto para get como para put. Y también me gustaría la luna en un palo, por favor, con un orden lateral de justicia.Java: mapas multiproceso: ¿cómo se comparan las implementaciones?

Las opciones que conozco son:

  • HashMap. Desastrosamente desenroscar seguro.

  • ConcurrentHashMap. Mi primera opción, pero esto tiene una gran huella de memoria, unos 2k por instancia.

  • Collections.sychronizedMap (HashMap). Eso está funcionando bien para mí, pero estoy seguro de que debe haber alternativas más rápidas.

  • Trove o Colt: creo que ninguno de estos es seguro para subprocesos, pero quizás el código podría adaptarse para ser seguro para subprocesos.

¿Alguna que otros? ¿Algún consejo sobre qué es mejor qué cuándo? ¿Algún algoritmo nuevo de hash realmente bueno con el que Java pueda usar una implementación?

Gracias de antemano por su contribución!

+0

No olvides la antigua HashTable. Obsoleto, pero aún se encuentra alrededor del código heredado de Java. – Uri

+1

@Uri: es Hashtable con la t minúscula. Hablando de herencia ... – BalusC

+0

También puede administrar hasta cierto punto la huella de ConcurrentHashMap ajustando el argumento del constructor concurrencyLevel. – Affe

Respuesta

0

Bueno, hay un Colt spruced-up en Apache Mahout. Todavía no está en el negocio actual. ¿Qué hay de malo en proteger el código con un bloque sincronizado? ¿Está esperando algún esquema endiabladamente complejo que contenga bloqueos para una granularidad menor que put o get?

Si puede codificar uno, por favor contrólelo a Mahout.

+0

Creo que necesitaría sincronizar tanto get como puts, ya que de lo contrario una repetición podría provocar que get() devuelva basura. Y esa sincronización estaría en el mapa en sí (no en las teclas). Funcionaría, pero se siente menos que óptimo. –

+0

Eso es lo que quise decir, más o menos. – bmargulies

0

Vale la pena echar un vistazo a los mapas hash persistentes en Clojure.

Estas son estructuras de datos inmutables y seguras para hilos con un rendimiento comparable al de los HashMaps de Java clásicos. Obviamente necesitarás envolverlos si quieres un mapa mutable, pero eso no debería ser difícil.

http://clojure.org/data_structures

6

Collections.synchronizedMap() simplemente hace que todos los métodos Mapsynchronized.

ConcurrentMap es realmente la interfaz que desea y hay varias implementaciones (por ejemplo, ConcurrentHashMap, ConcurrentSkipList). Tiene varias operaciones que Map no son importantes para las operaciones de fabricación de hilos. Además, es más granular que un Map sincronizado ya que una operación solo bloqueará una porción de la estructura de datos de respaldo en lugar de una operación completa.

3

No tengo experiencia en lo siguiente, pero una vez trabajé en un proyecto que juró por Javolution para tareas sensibles en tiempo real y memoria.

He observado en la API hay FastMap que dice que es seguro para subprocesos.Como digo, no tengo ni idea de si es bueno para usted, pero vale la pena un vistazo:

API for FastMap

Javolution Home

+0

Gracias - FastMap se ve interesante y altamente configurable. –

2

¡¡¡Es muy sorprendente que tenga una impresión de 2k !! ¿Qué hay de hacer la configuración de concurrencia ConcurrentHashMap más baja (por ejemplo, 2-3), y la optimización de su tamaño inicial (= hacer más pequeño).

No sé de dónde viene ese consumo de memoria, pero quizás tiene algo que ver con el mantenimiento de bloqueos rayados. Si baja la configuración de concurrencia, tendrá menos.

Si quiere un buen rendimiento con la seguridad de roscas lista para usar, ConcurrentHashMap es realmente agradable.

+0

Doh! No se me ocurrió que podía ajustar la configuración de ConcurrentHashMap. –

Cuestiones relacionadas