Linux, Open-source, Programação e Produtividade

List.contains(object)

Jonas Abreu em 25/03/2012

Em uma consultoria, no segundo dia de trabalho, subi o profiler para ter uma idéia geral de onde estava sendo gasto processamento na carga de uma página que demorava alguns segundos para carregar.

Assim que tudo estava pronto, acessei a página e vi o contador do método equals de uma entidade disparar para a lua. Basicamente para cada acesso, o equals da entidade era chamado 4 milhões de vezes.

Isso obviamente chamou a atenção e passei a procurar a razão disso.

A aplicação possuía uma cache contendo cerca de 1,5 milhões dessas entidades para não precisar ir ao banco a cada requisição. O problema é que essas entidades estavam armazenadas em um java.util.List.

A List é uma estrutura de dados muito boa para acesso posicional (se a implementação usar um array - java.util.ArrayList - para manter os dados), mas é péssima para fazer busca por dados, porque precisa checar um por um os elementos, o que faz no método List.indexOf. O List.contains delega a chamada para o List.indexOf. E esse era o problema.

Uma simples mudança de estrutura de dados (troquei para um java.util.concurrent.ConcurrentHashMap) fez com que o tempo de carga da página caísse 60%.

Basicamente, só use o List.contains em listas em que você tem certeza que o tamanho é pequeno (no máximo algumas centenas) e são feitas poucas chamadas a esse método. De resto, troque a estrutura de dados.

Creative Commons License
List.contains(object) de Jonas Abreu está licenciado sob Creative Commons License.