Desvantagem usando Closure
13/07/2012 15:10
1
Sou desenvolvedor java e recentemente entrei em um projeto que é em grails, que por sinal tem sido muito produtivo.

Eu gostei da ideia de usar closures, só que por falta de conhecimento eu as utilizo em quase tudo. Praticamente aboli os métodos tradicionais.
Minha perguinta é a seguinte:

Existe alguma vantagem ou desvantagem no grails usando closures quando queremos levar em conta o desempenho??
Tags: closures, desenpenho


2
Olá, Jonatas.

Amigo, quanto a performance, não conheço nenhum estudo que compare a velocidade de closures x métodos tradicionais. Porém fiz aqui uns testes com somas simples.
Resultado: Os testes com closure foram cerca de 10x mais rápidos que com métodos! :O Claro que e longe de ser um resultado conclusivo, mas foi surpreendente pra mim!

Agora, o uso de closures deve ser moderado, IMO. Particularmente ainda prefiro usar métodos tradicionais sempre que possível. Acho Closures menos semânticas, pois a definição de parâmetros é confusa e dificil de documentar. Dar manutenção em um projeto grande com muitos métodos é bem mais fácil do que o mesmo cheio de closures, IMO.


A saber, o teste que fiz foi:

public class PerfmTests {

@Test
public void testMetodos() {
MetClos mc = new MetClos()
1000.times{
mc.m1()
// depois com
// mc.m2(10,20)
}
Assert.assertNotNull('')
}

@Test
public void testClosures() {
MetClos mc = new MetClos()
1000.times{
mc.c1()
// depois com
// mc.c2(10,20)
}
Assert.assertNotNull('')
}

}

class MetClos {
def c1 = {
def s = 1 + 1
println s
}

def c2 = { n1,n2 ->
def s = n1 + n2
println s
}

void m1() {
def s = 1 + 1
println s
}

void m2(n1,n2) {
def s = n1 + n2
println s
}
}


Fiz no Eclipse com o plugin Groovy. Dai o JUnit me deu os tempos.


0
Oi Yoshiriro, fascinante este seu resultado hein?

será que o ganho na performance com closures não se deve ao fato de que a partir do segundo uso, independente do seu cliente, o custo de instanciação oculto já foi feito?

Digo: a closure tem seu contexto inicializado uma única vez (ao menos até aonde sei). A partir dai, nós não teríamos mais de ficar instanciando e tal.

Respondenao do Jonatas, eu nunca observei uma perda de performance devido ao fato de estar usando closures também não.


4
Um ponto negativo de trocar todos os métodos por closures é que cada closure vira um .class distinto, isso pode inchar bastante o perm space da jvm.
13/07/2012 18:41


0
Bacana, Rafael. Não sabia desse detalhe.


1
Muito obrigado!

Muito bom saber que podemos ganhar desempenho com closures, mas temos que nos atentar com a quantidade de .class que geraremos na nossa aplicação. Pode acabar piorando o que estavamos tentando melhorar.

Como a maioria dos casos, nada como uma boa análise antes de sair codando!



13/07/2012 20:22


0
Eu desconfio, não tenho certeza, de que talvez closures ocupem mais memória que métodos convencionais. Dado que cada closure é na realidade um objeto, você tem o custo de alocação para cada uma.

Mas pra tirar a prova disto, teria de fazer uma análise da compilação Groovy.


1
Pessoal fiquei curioso e fui pesquisar, mas será porque este teste deu diferente :-(
groovy-closures-significantly-slower-than-methods, eu tb não prestei muita atenção no código, mas me pareceu simples.
13/07/2012 20:30


1
A despeito de um class para cada closure, teste link também comenta isso groovy-closures-or-methods
13/07/2012 20:33


0
Oi Ibotirama e Yoshiriro,

em teoria, se o parâmetro recebido é um objeto que vêm de fora, e o código executado é apenas aquele presente dentro do bloco de código, não deveria haver diferença de performance, visto que o bloco de código (lendo como bloco de código um intervalo de instruções mesmo) é basicamente o mesmo.

Ai eu pergunto: o que será que ocorre a mais durante a execução de uma closure? Por que pensando em baixíssimo nível, não deveria haver diferença de performance, concordam?


1
Na minha opinião em baixo "nível" não teria diferença, pois no fim das contas o método também é uma variável com escopo, que contém um código, e recebe ou não parâmetros, não sei porque seria mais ou menos rápido (a não ser que as coisas não sejam tão simples assim rs), porém uma coisa é certa, digo duas, no Java 7, tem melhorias de performance para invoções dinâmicas, o que dará um up no groovy e nas closures, e neste artigo mostra como fazer um "cache" em closures para que elas ganhem em performance caso sejam muito repetidas, como em laços por exemplo : closure-caching-for-increased-performance-memoize
13/07/2012 21:05



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto