The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Text::Xslate::PP::Booster - Text::Xslate code generator for pure Perl

SYNOPSIS

    # If you want to check created codes, you can use it directly.
    use Text::Xslate::PP;
    use Text::Xslate::PP::Booster;

    my $tx      = Text::Xslate->new();
    my $booster = Text::Xslate::PP::Booster->new();

    my $optext  = q{<: $value :>};
    my $code    = $booster->opcode_to_perlcode_string( $tx->compile( $optext ) );
    my $coderef = $booster->opcode_to_perlcode( $tx->compile( $optext ) );
    # $coderef takes a Text::Xslate::PP::State object

DESCRIPTION

This module is a pure Perl engine, which is much faster than Text::Xslate::PP::Opcode, but might be less stable.

The motivation to implement this engine is the performance. You know the default pure Perl engine was really slow. For example:

    $ XSLATE=pp=opcode perl -Mblib benchmark/others.pl
    Perl/5.10.1 i686-linux
    Text::Xslate/0.1025
    Text::MicroTemplate/0.11
    Template/2.22
    Text::ClearSilver/0.10.5.4
    HTML::Template::Pro/0.94
    ...
    Benchmarks with 'list' (datasize=100)
             Rate Xslate     TT     MT    TCS     HT
    Xslate  155/s     --   -52%   -83%   -94%   -95%
    TT      324/s   109%     --   -64%   -88%   -90%
    MT      906/s   486%   180%     --   -66%   -73%
    TCS    2634/s  1604%   713%   191%     --   -21%
    HT     3326/s  2051%   927%   267%    26%     --

All right, it is slower than Template-Toolkit! But now Text::Xslate::PP::Booster is available, and is as fast as Text::MicroTemplate:

    $ XSLATE=pp perl -Mblib benchmark/others.pl
    ...
    Benchmarks with 'list' (datasize=100)
             Rate     TT Xslate     MT    TCS     HT
    TT      330/s     --   -63%   -65%   -87%   -90%
    Xslate  896/s   172%     --    -5%   -65%   -73%
    MT      941/s   185%     5%     --   -63%   -72%
    TCS    2543/s   671%   184%   170%     --   -24%
    HT     3338/s   912%   272%   255%    31%     --

Text::Xslate::PP becomes much faster than the default pure Perl engine!

The engine is enabled with $ENV{ENV}='pp=booster'.

APIs

new

Constructor.

    $booster = Text::Xslate::PP::Booster->new();

opcode_to_perlcode

Takes a virtual machine code created by Text::Xslate::Compiler, and returns a code reference.

  $coderef = $booster->opcode_to_perlcode( $ops );

The code reference takes Text::Xslate::PP::State object in Xslate runtime processes. Don't execute this code reference directly.

opcode_to_perlcode_string

Takes a virtual machine code created by Text::Xslate::Compiler, and returns a perl subroutine code text.

  $str = $booster->opcode_to_perlcode_string( $ops );

ABOUT BOOST CODE

Text::Xslate::PP::Booster creates a code reference from a virtual machine code.

    $tx->render_string( <<'CODE', {} );
    : macro foo -> $arg {
        Hello <:= $arg :>!
    : }
    : foo($value)
    CODE

Firstly the template data is converted to opcodes:

    pushmark
    fetch_s "value"
    push
    macro "foo"
    macrocall
    print
    end
    macro_begin "foo"
    print_raw_s "    Hello "
    fetch_lvar 0
    print
    print_raw_s "!\n"
    macro_end

And the booster converted them into a perl subroutine code (you can get that code by XSLATE=dump=pp).

    sub {
        no warnings 'recursion';
        my ( $st ) = @_;
        my ( $sv, $pad, %macro, $depth );
        my $output = q{};
        my $vars   = $st->{ vars };

        $pad = [ [ ] ];

        # macro

        $macro{"foo"} = $st->{ booster_macro }->{"foo"} ||= sub {
            my ( $st, $pad ) = @_;
            my $vars = $st->{ vars };
            my $output = q{};

            Carp::croak('Macro call is too deep (> 100) on "foo"') if ++$depth > 100;

            # print_raw_s
            $output .= "        Hello ";


            # print
            $sv = $pad->[ -1 ]->[ 0 ];
            if ( ref($sv) eq 'Text::Xslate::EscapedString' ) {
                $output .= $sv;
            }
            elsif ( defined $sv ) {
                $sv =~ s/($html_unsafe_chars)/$html_escape{$1}/xmsgeo;
                $output .= $sv;
            }
            else {
                _warn( $st, "foo", 10, "Use of nil to print" );
            }

            # print_raw_s
            $output .= "!\n";


            $depth--;
            pop( @$pad );

            $output;
        };


        # process start

        # ex_print_raw
        $output .= $macro{ "foo" }->( $st, push_pad( $pad, [ $vars->{ "value" } ] ) );


        # process end

        return $output;
    }

So it makes the runtime speed much faster. Of course, its initial converting process costs time and memory.

SEE ALSO

Text::Xslate::PP

AUTHOR

Makamaka Hannyaharamitu <makamaka at cpan.org>

LICENSE AND COPYRIGHT

Copyright (c) 2010 by Makamaka Hannyaharamitu (makamaka).

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.