[RESOLVIDO] List e StringBuilder, limpar conteudo ou reinstanciar

7 respostas
jks1903

Pessoal, tenho uma duvida e gostaria de uma opiniao.

Em alguns projetos, em que utilizo StringBuilders e/ou Lists, em determinado momento necessito limpar o conteudo dos objetos.

Para as listas, em geral faço List.clear e na StringBuilder invoco o método setLength(0).

Queria saber o que seria melhor, em questoes de desempenho, utilizar esses métodos mesmo ou instanciar como um novo, algo como:

List lista = new List e StringBuilder string = new StringBuilder.

Obrigado.

7 Respostas

A

Para desempenho, isso vai ser irrelevante na maior parte do tempo.

Mas deveria se preocupar com a necessidade de limpar objetos.
Se eles continuam “vivos” para serem reutilizados, então talvez estejam com escopo maior do que devia.

Ter um atributo de classe ao invés de uma variável local, por exemplo.

jks1903

AbelBueno:
Para desempenho, isso vai ser irrelevante na maior parte do tempo.

Mas deveria se preocupar com a necessidade de limpar objetos.
Se eles continuam “vivos” para serem reutilizados, então talvez estejam com escopo maior do que devia.

Ter um atributo de classe ao invés de uma variável local, por exemplo.

Na verdade é um atributo de classe sim.
um exemplo de aplicações com listas é um caso que preciso carregar um arquivo excel para uma aplicação. As vezes as planilhas possem muitos registros, e antes de confirmar a importação eu apresento os valores importados pro usuário, para que o mesmo possa selecionar quais registros deseja importar. E o atributo de classe é usado porque preciso compartilhar essa lista com varios metodos da mesma. Porém, em determinado momento o usuário pode querer carregr outro arquivo, onde essa lista deve ser “zerada”.
Aí dessa necessidade me surgiu a dúvida do tópico.

Obrigado.

E

Eu limparia a lista ou o StringBuilder, porque outra parte do seu código pode estar referenciando esse mesmo objeto (sabe como é que é, código grande e bagunçado acaba ficando assim).
Se você simplesmente reinstanciar, pode acabar ficando com dados incoerentes.

E

Para limpar a lista, nada tão simples quanto chamar o método clear()
No caso do StringBuilder, pode usar setLength (0).

jks1903

entanglement:
Eu limparia a lista ou o StringBuilder, porque outra parte do seu código pode estar referenciando esse mesmo objeto (sabe como é que é, código grande e bagunçado acaba ficando assim).
Se você simplesmente reinstanciar, pode acabar ficando com dados incoerentes.

Na verdade essa dúvida é mais didática do que prática.
É que verifiquei a implementação do método clear, como segue abaixo:

public void clear() {
	modCount++;

	// Let gc do its work
	for (int i = 0; i < size; i++)
	    elementData[i] = null;

	size = 0;
    }

Nao consegui descobrir o que é a variável modCount, mas no mais, pelo que entendi esse metodo percorre toda a lista, deixando cada elemento como null. Em se tratando de listas muito extensas esse trabalho pode ser custoso e por isso havia pensado na possibilidade de uma nova instância, que se nao me engano apenas aloca outro espaço de memória para a nova lista.

MAs referente a ficar com dados incoerentes acho que não vá ocorrer, visto que chamando o método clear, possíveis blocos de código que poderiam estar referenciando esse objeto no momento também perderiam a referência.

Me corrijam se estiver errado.

Obrigado.

E

O JIT (Just-in-time compiler) reconhece que você está tentando limpar um array setando todas as posições para null e gera um código bem eficiente para zerar todas as referências (semelhante ao código do “memset” do C, que zera um bloco de memória usando algumas instruções especiais do processador, como REP STOSD ou coisa parecida). Não é isso que vai deixar seu programa mais lento.

O que pode ocorrer, eu concordo, é o seguinte: digamos que seu ArrayList tenha ficado com 10.000 posições.
Quando você usa “clear” ele não realoca o array de referências que você acabou de ver, ele somente o limpa.
Se o seu ArrayList pode acabar ficando grande de novo, você já economiza algumas desalocações e realocações que já foram feitas (como você deve saber, o array inicialmente começa pequeno e depois é realocado quando você vai inserindo elementos no ArrayList).
Mas se seu ArrayList não vai ficar mais com esse tamanho grande de novo, ele vai ocupar espaço desnecessariamente.

Portanto, tudo depende do que você está fazendo em seu programa.

jks1903

entanglement:
O JIT (Just-in-time compiler) reconhece que você está tentando limpar um array setando todas as posições para null e gera um código bem eficiente para zerar todas as referências (semelhante ao código do “memset” do C, que zera um bloco de memória usando algumas instruções especiais do processador, como REP STOSD ou coisa parecida). Não é isso que vai deixar seu programa mais lento.

O que pode ocorrer, eu concordo, é o seguinte: digamos que seu ArrayList tenha ficado com 10.000 posições.
Quando você usa “clear” ele não realoca o array de referências que você acabou de ver, ele somente o limpa.
Se o seu ArrayList pode acabar ficando grande de novo, você já economiza algumas desalocações e realocações que já foram feitas (como você deve saber, o array inicialmente começa pequeno e depois é realocado quando você vai inserindo elementos no ArrayList).
Mas se seu ArrayList não vai ficar mais com esse tamanho grande de novo, ele vai ocupar espaço desnecessariamente.

Portanto, tudo depende do que você está fazendo em seu programa.

Entendi, depende da situação mesmo então.
Nesse caso que usei de exemplo, acho que o clear (como estou fazendo) é realmente mais indicado, visto que quando é necessário limpar a lista, a nova lista terá tamanho, se nao igual, bem semelhante à anterior.

Obrigado pelo esclarecimento.

Criado 3 de outubro de 2012
Ultima resposta 4 de out. de 2012
Respostas 7
Participantes 3