[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