Qual é a biblioteca Java Collections mais eficiente?
Alguns anos atrás, eu fiz muito Java e tive a impressão de que o trove é a melhor (mais eficiente) implementação de Coleções Java. Mas quando li as respostas para a pergunta " Bibliotecas Java gratuitas mais úteis? ", Notei que o tesouro quase não é mencionado. Então, qual biblioteca Java Collections é melhor agora?
ATUALIZAÇÃO: Para esclarecer, quero saber principalmente qual biblioteca usar quando tiver que armazenar milhões de entradas em uma tabela de hash etc. (preciso de um pequeno tempo de execução e presença de memória).
java
collections
Frank
fonte
fonte
Respostas:
Da inspeção, parece que o Trove é apenas uma biblioteca de coleções para tipos primitivos - não é como se quisesse adicionar muita funcionalidade às coleções normais no JDK.
Pessoalmente (e sou tendencioso), adoro o Guava (incluindo o projeto anterior do Google Java Collections). Isso facilita várias tarefas (incluindo coleções), de uma maneira que seja pelo menos razoavelmente eficiente. Dado que as operações de coleção raramente formam um gargalo no meu código (na minha experiência), isso é "melhor" do que uma API de coleções que pode ser mais eficiente, mas não torna meu código tão legível.
Dado que a sobreposição entre o Trove e a goiaba é praticamente nula, talvez você possa esclarecer o que realmente está procurando em uma biblioteca de coleções.
fonte
A questão é (agora) sobre o armazenamento de muitos dados, que podem ser representados usando tipos primitivos como
int
, em um mapa. Algumas das respostas aqui são muito enganosas na minha opinião. Vamos ver o porquê.Modifiquei o benchmark do trove para medir o tempo de execução e o consumo de memória. Também adicionei o PCJ a esse benchmark, que é outra biblioteca de coleções para tipos primitivos (eu uso esse extensivamente). O benchmark 'oficial' do tesouro não compara o IntIntMaps ao Java Collection
Map<Integer, Integer>
, provavelmente armazenarIntegers
e armazenarints
não é o mesmo do ponto de vista técnico. Mas um usuário pode não se importar com esses detalhes técnicos, ele deseja armazenar dados representáveis comints
eficiência.Primeiro, a parte relevante do código:
Presumo que os dados sejam primitivos
ints
, o que parece sensato. Mas isso implica em uma penalidade de tempo de execução para o java util, devido ao boxing automático, que não é necessário para as estruturas de coleções primitivas.Os resultados do tempo de execução (sem
gc()
chamadas, é claro) no WinXP, jdk1.6.0_10:Embora isso possa já parecer drástico, esse não é o motivo para usar essa estrutura.
O motivo é o desempenho da memória. Os resultados para um mapa contendo 100000
int
entradas:O Java Collections precisa de mais de três vezes a memória em comparação com as estruturas de coleta primitivas. Ou seja, você pode manter três vezes mais dados na memória, sem recorrer às E / S de disco, o que diminui o desempenho do tempo de execução por magnitudes. E isso importa. Leia alta escalabilidade para descobrir o porquê.
Na minha experiência, o alto consumo de memória é o maior problema de desempenho do Java, o que obviamente resulta em pior desempenho do tempo de execução. As estruturas de coleta primitivas podem realmente ajudar aqui.
Então: Não, java.util não é a resposta. E "adicionar funcionalidade" às coleções Java não é o ponto de perguntar sobre eficiência. Além disso, as coleções modernas do JDK " não superam nem as coleções especializadas da Trove".
Isenção de responsabilidade: A referência aqui está longe de ser completa, nem perfeita. O objetivo é esclarecer a questão, que experimentei em muitos projetos. Coleções primitivas são úteis o suficiente para tolerar API duvidosa - se você trabalha com muitos dados.
fonte
hashCode()
. Você recebeint
como a chave.Eu sei que este é um post antigo e há uma tonelada de respostas aqui. Mas, as respostas acima são superficiais e simplificadas em termos de sugestão de uma biblioteca. Não existe uma biblioteca que se dê bem nos vários benchmarks apresentados aqui. A única conclusão que tirei é que se você se preocupa com desempenho e memória e, especificamente, com tipos primitivos, vale mais a pena olhar para as alternativas não jdk.
Aqui está uma análise mais sólida, em termos de mecânica de referência e das bibliotecas cobertas. Este é um tópico na lista de desenvolvedores mahout.
As bibliotecas cobertas são
Atualização em junho de 2015 : Infelizmente, os benchmarks originais não estão mais disponíveis e, além de um pouco desatualizados. Aqui estão alguns benchmarks recentes (janeiro de 2015) feitos por outra pessoa. Não é tão abrangente nem possui as ferramentas exploratórias interativas como o link original.
fonte
Como outros comentaristas notaram, a definição de "eficiente" lança uma ampla rede. No entanto, ninguém ainda mencionou a biblioteca Javolution .
Alguns dos destaques:
A distribuição Javolution inclui um conjunto de benchmarks para que você possa ver como eles se comparam com outras bibliotecas / coleções internas.
fonte
Algumas bibliotecas de coleção a serem consideradas:
Em primeiro lugar, procuraria a biblioteca de coleções do JDK. Ele cobre as coisas mais comuns que você precisa fazer e, obviamente, já está disponível para você.
O Google Collections é provavelmente a melhor biblioteca de alta qualidade fora do JDK. É muito usado e bem suportado.
O Apache Commons Collections é mais antigo e sofre um pouco com o problema "muitos cozinheiros", mas também possui muitas coisas úteis.
O Trove possui coleções muito especializadas para casos como valores / chaves primitivas. Atualmente, descobrimos que em JDKs modernos e com as coleções Java 5+ e casos de uso simultâneos, as coleções JDK superam até as coleções Trove especializadas.
Se você tem casos de uso de simultaneidade realmente alta, deve definitivamente verificar coisas como o NonBlockingHashMap na lib de alta escala, que é uma implementação sem bloqueios e pode pisar no ConcurrentHashMap se você tiver o caso de uso correto.
fonte
java.util
Desculpe a resposta óbvia, mas para a maioria dos usos, as coleções Java padrão são mais que suficientes.
fonte
Para armazenar milhões
String
em um mapa, consulte http://code.google.com/p/flatmapfonte
Sou desenvolvedor de coleções felizes de coleções felizes no forge-source
fonte
O ConcurrentHashMap e o
java.util.concurrent
pacote devem ser mencionados, se você planeja usar o HashMap em vários threads. uma pegada de memória pequena é avaliada, pois isso faz parte do java padrão.fonte
Depende de como definimos "eficiente".
Toda estrutura de dados tem seu próprio comportamento Big-Oh para leitura, gravação, iteração, presença de memória, etc. É provável que uma lista vinculada em uma biblioteca seja a mesma que em qualquer outra. E um mapa de hash será mais rápido para ler O (1) do que uma lista vinculada O (n).
Isso não soa como "mais eficiente". Parece "mais popular" para mim.
Apenas alguns comentários - nunca ouvi falar disso e não conheço ninguém que o tenha usado. As coleções incorporadas ao JDK, Google ou Apache Commons são bem conhecidas para mim.
fonte
O Trove oferece algumas vantagens.
Dito isto, muito foi feito para melhorar as coleções do jdk desde que o trove foi escrito.
São as estratégias de hash que o tornam atraente para mim ... no Google, para descobrir e ler sua visão geral.
fonte
Se você deseja armazenar milhões de registros em uma tabela de hash, é provável que você tenha problemas de memória. Isso aconteceu comigo quando tentei criar um mapa com 2,3 milhões de objetos String, por exemplo. Fui com o BerkeleyDB , que é muito maduro e tem um bom desempenho. Eles possuem uma API Java que envolve a API Collections, para que você possa criar facilmente mapas arbitrariamente grandes, com muito pouco espaço para memória. O acesso será mais lento (como é armazenado no disco).
Pergunta de acompanhamento : existe uma biblioteca decente (e eficiente) e bem mantida para coleções imutáveis? O Clojure tem um excelente suporte para isso e seria bom ter algo semelhante para Java.
fonte