[SP-pm] Duvida primaria
Eden Cardim
edencardim at gmail.com
Thu Oct 21 08:07:32 PDT 2010
>>>>> "Nilson" == Nilson Santos Figueiredo <acid06 em gmail.com> writes:
Nilson> 2010/10/21 russoz em gmail.com <russoz em gmail.com>:
>> Similarmente, a inicialização das tabelas de lookup/dispatch
>> (qualquer flavour) NÃO fazem parte do bloco de código. Ou,
>> falando de outra forma: sim, você está certo, faz diferença em
>> diversos casos. But then again, se você escolhe um caso
>> mal-codificado com dispatch e compara com um bem-codificado com
>> given/when, não é exatamente algo muito justo, é? :-)
Nilson> Não é questão de mal ou bem codificado, é uma questão de
Nilson> necessidade.
Nilson> Sempre que você precise, por algum motivo, executar algum de
Nilson> N casos de código em que o código em si depende do escopo
Nilson> atual, você não poderia declarar a dispatch table de
Nilson> fora. Por exemplo, você está escrevendo uma função que
Nilson> retorna funções que usa variáveis do escopo local no
Nilson> closure.
Nesse caso o given/when perde mais feio ainda porque pode-se aplicar
currying e não fazer lookup algum durante a construção da closure, e
isso porque o switch só tem dois casos de branching nesse seu exemplo,
com mais casos é mais feio ainda. Além de que a versão com currying tem
a vantagem de que pode-se invocar $dispatch->{$style}->($content) de
qualquer ponto do código sem ter que passar inutilmente pela
verificação. A subrotina gerada vai ter um overhead um pouco maior do
que a versão gerada com given/when porque perl não é puramente funcional
então não dá pra aplicar as otimizações que se aplicariam nesse caso,
mas aí é outra questão. Eu continuo enfatizando a legibilidade,
particularmente, acho a versão com curry mais legível.
Execução do lookup:
Rate switch curry
switch 152207/s -- -21%
curry 193050/s 27% --
Execução da subrotina gerada:
Rate curried switched
curried 751880/s -- -56%
switched 1724138/s 129% --
O código:
use warnings;
use strict;
use feature 'switch';
use Benchmark qw(:all);
# inicio curry
my $dispatch = {
html => sub {
my ( $tag_name, $content ) = @_;
return "<$tag_name>$content</$tag_name>";
},
xml => sub {
my ( $tag_name, $content ) = @_;
return "<$tag_name"
. ( length $content ? ">$content</$tag_name>" : "/>" );
}
};
sub tag_generator_curry {
my ( $tag_name, $style ) = @_;
return sub { $dispatch->{$style}->($tag_name, @_) };
}
#fim curry
# inicio switch
sub tag_generator_switch {
my ( $tag_name, $style ) = @_;
given ($style) {
when ('html') {
return sub {
my $content = shift // '';
"<$tag_name>$content</$tag_name>";
}
}
when ('xml') {
return sub {
my $content = shift // '';
"<$tag_name"
. ( length $content ? ">$content</$tag_name>" : "/>" );
}
}
}
}
# fim switch
my @styles = qw(xml html);
sub call_curry { tag_generator_curry('whatever', $styles[int rand @styles]) }
sub call_switch { tag_generator_switch('whatever', $styles[int rand @styles]) }
cmpthese(
10**6,
{
curry => \&call_curry,
switch => \&call_switch,
}
);
my $curried = tag_generator_curry('whatever', 'xml');
my $switched = tag_generator_switch('whatever', 'xml');
cmpthese(
10**6,
{
curried => $curried,
switched => $switched,
}
);
--
Eden Cardim Need help with your Catalyst or DBIx::Class project?
Code Monkey http://www.shadowcat.co.uk/catalyst/
Shadowcat Systems Ltd. Want a managed development or deployment platform?
http://blog.edencardim.com/ http://www.shadowcat.co.uk/servers/
More information about the SaoPaulo-pm
mailing list