[Dúvida] Quantidade de variáveis locais

9 respostas
rubensdemelo

Pessoal, sempre tive uma curiosidade. Em relação aos trechos de código abaixo:

[...]

String qualquerCoisa= form.get(qualquerCoisa);
List<Object> lista = new ArrayList<Object>();
lista = servico.buscarAlgo(qualquerCoisa);

[...]
[...]

List<Object> lista = servico.buscarAlgo(form.get(qualquerCoisa));

[...]

Apesar de fazerem a mesma coisa, o 1º trecho é sem dúvida muito mais “legível” aos nossos olhos. O entendimento é bem mais fácil. Logo, para quem vai dar manutenção/revisar/debugar fica muito mais fácil, porém o 2º trecho é mais compacto.

A minha dúvida é em relação a performace (não sei bem se o termo seria este, mas…).
Qual dos trechos executaria mais rápido, ou daria menos trabalho ao compilador e a JVM executaria mais rapidamente?

Valeu

9 Respostas

rodpuc

Escreva sempre o mais legível. Se houver qualquer coisa que melhore a performance, existe uma coisa no compilador chamada “otimização”, ele é inteligente o suficiente para transformar seu código em um mais eficiente. Resumindo, não se preocupe com esse tipo de ganho de performance, o compilador faz isso por vc, deixe o seu código o mais legível possível.

Abraço

T

Uma vantagem de usar mais variáveis (em vez de menos variáveis) é que frequentemente você acaba achando trechos comuns de código que podem reusar o valor já calculado.

Nada me irrita mais que aqueles fulanos que acham que recalcular a mesma coisa repetidas vezes, para economizar variáveis (ou por pura preguiça ou copy & paste, o que é mais comum), é melhor.

O compilador não consegue fazer esse tipo de otimização (verificar que um mesmo trecho de código, repetido inúmeras vezes, só precisa ser calculado uma vez) se o tal trecho tiver chamadas a métodos, porque o tal método pode retornar resultados diferentes a cada vez que é chamado. Mesmo um getter simples só é otimizado pelo compilador em determinadas situações.

Então, se você souber que tal trecho realmente não se altera de um ponto para outro do código, crie uma variável e calcule o resultado apenas uma vez.

rubensdemelo

thingol:
Uma vantagem de usar mais variáveis (em vez de menos variáveis) é que frequentemente você acaba achando trechos comuns de código que podem reusar o valor já calculado.

Nada me irrita mais que aqueles fulanos que acham que recalcular a mesma coisa repetidas vezes, para economizar variáveis (ou por pura preguiça ou copy & paste, o que é mais comum), é melhor.

O compilador não consegue fazer esse tipo de otimização (verificar que um mesmo trecho de código, repetido inúmeras vezes, só precisa ser calculado uma vez) se o tal trecho tiver chamadas a métodos, porque o tal método pode retornar resultados diferentes a cada vez que é chamado. Mesmo um getter simples só é otimizado pelo compilador em determinadas situações.

Então, se você souber que tal trecho realmente não se altera de um ponto para outro do código, crie uma variável e calcule o resultado apenas uma vez.

Neste caso então, seria como usar a variável lista, do 2º trecho, em outras partes do código, ao invés de dar CRTL+C e CTRL+V no 1º treco, e replica-lo?

T

Sim senhor.
Só não se esqueça que você tem de tomar um pouco de cuidado: não fique criando variáveis de instância (não as locais) só para evitar recalcular certas coisas. Pode ser que você acabe ficando meio “complicado” nessa história.
Mesmo o uso de variáveis locais para evitar o recálculo você tem de tomar um pouco de cuidado, para evitar que o tal valor fique disponível em algum lugar inadequado. Use o menor escopo possível para uma variável local.

rubensdemelo

thingol:
Sim senhor.
Só não se esqueça que você tem de tomar um pouco de cuidado: não fique criando variáveis de instância (não as locais) só para evitar recalcular certas coisas. Pode ser que você acabe ficando meio “complicado” nessa história.
Mesmo o uso de variáveis locais para evitar o recálculo você tem de tomar um pouco de cuidado, para evitar que o tal valor fique disponível em algum lugar inadequado. Use o menor escopo possível para uma variável local.

Beleza cara, valeu.

sergiotaborda

Quando vc usa java vc não se preocupa com essas coisas. Isso é o tipo de “otimização” que se faz em outras linguagens , sobretudo as pré-java. O Compilador JIT é muito mais inteligente que um compilador normal e pode até mudar o seu codigo.

Encadear as chamadas é interessante se for legivel, mas as boas práticas pedem que não abuse disso.
Realmente a opção 1 é melhor.

Se vc quer informar ao compilador e ao programador que lerá seu codigo que vc está usando a variável apenas para aumentar a legebilidade vc coloca um final nessa variável.

Variáveis locais e final são sinónimos de “tou chamando isto aqui com um nome para efeitos de leitura humana”
O compilador , ao ver o final, tem a certeza que pode fazer o inline ( que seria equivalente À opção 2) e ele faz.
No fim ele não aloca essa variável quando o programa corre.

Só que detalhe : isso é o que o JIT da sun faz. Outros podem fazer diferente. Logo, não ha como garantir que um certo codigo escrito de certa forma é mais rápido que outra forma. Esse tipo de otimização não se faz em java.

Enfim, se vc quer escrever o codigo bem, use a opção 1 e coloque final nas variáveis que está usando apenas para clareza. Mas não pense em rapidez de execução. Pense apenas que assim é mais claro para os outros programadores porque é a convenção.

rubensdemelo

Tá certo sergiotaborda, valeu pela explicação.

A

[quote=rubensdemelo]Pessoal, sempre tive uma curiosidade. Em relação aos trechos de código abaixo:

[...]

String qualquerCoisa= form.get(qualquerCoisa);
List<Object> lista = new ArrayList<Object>();
lista = servico.buscarAlgo(qualquerCoisa);

[...]
[...]

List<Object> lista = servico.buscarAlgo(form.get(qualquerCoisa));

[...]

Concordo que no 1.º codigo é mais correto.
Para mim a JVM vai ter o mesmo trabalho, pois ela vai ter que alocar o valor do parametro em algum lugar da memória.

no segundo código de qualquer forma teria que instanciar um arrayList… a não ser que o método retorne um List… ou subclasse.

T

Isto (de inicializar uma variável com um objeto e a seguir jogá-lo fora) é típico de programadores VB 6 (onde você usava algo parecido com isso, acho que é porque senão o VB 6 se confundia e as coisas não funcionavam direito):

List<Object> lista = new ArrayList<Object>();  
 lista = servico.buscarAlgo(qualquerCoisa);

é mais ou menos em VB 6 (descontando o fato que não existem nem generics nem listas em VB 6):

Dim lista As New Collection
Set lista = servico.buscarAlgo(qualquerCoisa) 'rem aqui você jogou fora a Collection criada na linha 1

O certo seria:

List<Object> lista; // não crio objetos só para jogá-los fora na linha seguinte
 lista = servico.buscarAlgo(qualquerCoisa);

e, em VB 6,

Dim lista As Collection 'rem Aqui  declaro...
Set lista = servico.buscarAlgo(qualquerCoisa) 'rem E aqui eu pego a coleção.
Criado 13 de agosto de 2009
Ultima resposta 14 de ago. de 2009
Respostas 9
Participantes 5