Ruby Inline vs Block vs Proc

Algo que estranhei bastante ao começar a programar em Ruby foi sem duvida os Blocos e os Procs, para alguém que tinha Java como linguagem preferida foi algo uma tanto “absurdo”.

Pensar mas para que raio é isto!?!? Se tenho um objecto porque não chamo simplesmente os seus métodos e pronto!?!?

Depois de algum tempo comecei a adaptar-me ao uso dos blocos a nível de código realmente consegue simplificar muita a vida do programar e tornar as muitos casos as coisas bem mais simples.

Então ai surgiu outra duvida! Será que o uso de blocos e procs trás melhores ou piores níveis de performance face ao simples código inline ?

Depois de alguma pesquisa encontrei o seguinte artigo http://www.pluralsight.com/community/blogs/dbox/archive/2006/05/09/23068.aspx  onde era discutido exactamente essa questão.

O autor questiona-se o porque da adoração dos programadores de Ruby pelos blocos em relação ao código inline, para tentar chegar a algumas conclusões ele cria o seguinte código.

require "benchmark"

IterationCount = 1000000
$x = 0

def UseBlock
    yield
end

def UseProc(&p)
    p.call
end

def InlineStatic()
    i = 0
    while (i < IterationCount)
        $x = $x + 1
        i = i + 1
    end
end

def InlineLocal()
    i = 0
    y = 0
    while (i < IterationCount)
        y = y + 1
        i = i + 1
    end
end

def BlockStatic()
    i = 0
    while (i < IterationCount)
        UseBlock do $x = $x + 1 end
        i = i + 1
    end
end

def BlockLocal()
    i = 0
    y = 0
    while (i < IterationCount)
        UseBlock do y = y + 1 end
        i = i + 1
    end
end

def ProcStatic()
    i = 0
    while (i < IterationCount)
        UseProc do $x = $x + 1 end
        i = i + 1
    end
end

def ProcLocal()
    i = 0
    y = 0
    while (i < IterationCount)
        UseProc do y = y + 1 end
        i = i + 1
    end
end

Benchmark.bm { |r|
    r.report { InlineStatic() }
    r.report { InlineLocal() }
    r.report { BlockStatic() }
    r.report { BlockLocal() }
    r.report { ProcStatic() }
    r.report { ProcLocal() }
}

Ao executar este código no Ruby 1.8.7 obtive os seguintes resultados


user     system   total     real
0.570000 0.000000 0.570000 ( 0.584075)
0.500000 0.000000 0.500000 ( 0.510654)
1.320000 0.330000 1.650000 ( 1.662194)
1.280000 0.270000 1.550000 ( 1.555471)
3.240000 0.350000 3.590000 ( 3.623273)
3.100000 0.390000 3.490000 ( 3.507118)

Como podemos ver os resultados difererem como podemos ver o codigo inline é o com melhor performance, seguido pelos blocos com aproximadamente 3 vezes menos performance e por fim os procs com 7 vezes menos performance que o inline.

Claramente os Procs oferencem uma menor performance face ao inline e aos blocos. Em relação ao inline vs blocos é algo discutivél, cabe ao programador avaliar se a diferença é significativa para o objectivo em questão, tambem há que ter em consideração que se trata apenas de uma exemplo com contagem de 0 a 1000000, ao usar outras sequencias de codigo é possivel obter outros resultados embora os procs vejam sempre a estar em ultimo lugar dado que o uso do yield nos blocos cria um proc apenas parcial e não total como no caso do proc.

A titulo de curiosidade resolvi executar o mesmo codigo no Ruby 1.9.0 e os resultados embora tenham mantido a mesma sequencia no que toca a performance, tiveram valores um tanto diferentes…


user system total real
0.080000 0.000000 0.080000 ( 0.078453)
0.060000 0.000000 0.060000 ( 0.056817)
0.190000 0.000000 0.190000 ( 0.187863)
0.160000 0.000000 0.160000 ( 0.169452)
0.580000 0.000000 0.580000 ( 0.580614)
0.570000 0.000000 0.570000 ( 0.567870)

Os valores são claramente muito inferiores aos do Ruby 1.8 é sem duvida uma grande melhoria no que toca á performance do Ruby!

E tambem uma aproximação da performance entre o código inline e os blocos face aos blocos e proc que ficam ainda mais distanciados do que anteriormente.

Anúncios

One thought on “Ruby Inline vs Block vs Proc

  1. Данная статья имеет четко выраженный информативный стиль, большое спасибо Вам.

    Assim como quem diz:
    This article is clear and informative style, thank you.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão /  Alterar )

Google photo

Está a comentar usando a sua conta Google Terminar Sessão /  Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão /  Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão /  Alterar )

Connecting to %s