Strange performance problem inside POE

Jan Sundberg <[email protected]>
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
Hello.

I'm writing a regexp based parser based on the perlop manpage /\G.../gc 
example:

                LOOP:
                   {
                     print(" digits"),         redo LOOP if 
/\G\d+\b[,.;]?\s*/gc;
                     print(" lowercase"),      redo LOOP if 
/\G[a-z]+\b[,.;]?\s*/gc;
                     print(" UPPERCASE"),      redo LOOP if 
/\G[A-Z]+\b[,.;]?\s*/gc;
                     print(" Capitalized"),    redo LOOP if 
/\G[A-Z][a-z]+\b[,.;]?\s*/gc;
                     print(" MiXeD"),          redo LOOP if 
/\G[A-Za-z]+\b[,.;]?\s*/gc;
                     print(" alphanumeric"),   redo LOOP if 
/\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
                     print(" line-noise"),     redo LOOP if 
/\G[^A-Za-z0-9]+/gc;
                     print ". That's all!\n";
                   }

In converts long PDU strings to anonymous hashes using:

# testing wrapper

while (<>) {
    chomp;
    my $str = $_;
    my $h = dict(\$str);
    print Dumper($h);
}

# converts a string to a nested anonymous hash

sub dict {
    my $msg = shift;
    $$msg =~ /\G\{/gc;
    my $h = {};
    while ($$msg =~ /\G\s*(\S+?)\s*=\s*/gc) {
    my $key = $1;
    if ($$msg =~ /\G(?=\{)/gc) {
        $h->{$key} = dict($msg);
    } elsif ($$msg =~ /\G([^\|\}]*)/gc) {
        my $value = $1;
        $h->{$key} = $value;
    }
    return $h if $$msg =~ /\G\}/gc;
    $$msg =~ /\G\|/gc;
    }
}

It's *very* fast due to nonexistent string manipulation and pos() offset 
indexing.

Here's the strange thing: if I use the *exactly* same code inside a POE 
Filter it becomes more than 10 times slower!

A small SmallProf comparison:

FAST version in a simple script:

        0   0.00000   0.00000    22:sub dict {
      853   0.00051   0.00000    23:    my $msg = shift;
      853   0.00044   0.00000    24:    $$msg =~ /\G\{/gc;
      853   0.00105   0.00000    25:    my $h = {};
      853   0.00373   0.02000    26:    while ($$msg =~ 
/\G\s*(\S+?)\s*=\s*/gc) {
    10053   0.03222   0.15000    27: my $key = $1;
    10053   0.02309   0.09000    28: if ($$msg =~ /\G(?=\{)/gc) {
        0   0.00000   0.00000    29:     $h->{$key} = dict($msg);
        0   0.00000   0.00000    30:#     print "DICT $key => ", Dumper($h-
        0   0.00000   0.00000    31: } elsif ($$msg =~ /\G([^\|\}]*)/gc) {
     9201   0.01445   0.17000    32:     my $value = $1;
     9201   0.03373   0.13000    33:     $h->{$key} = $value;
        0   0.00000   0.00000    34:#     print "SCALAR $key => $value\n";
        0   0.00000   0.00000    35: }
    10053   0.01924   0.17000    36: return $h if $$msg =~ /\G\}/gc;
     9200   0.03602   0.16000    37: $$msg =~ /\G\|/gc;
        0   0.00000   0.00000    38:    }
        0   0.00000   0.00000    39:}

SLOW version in a POE/Filter subclass:

        0   0.00000   0.00000    65:sub dict {
      871   0.00127   0.01000    66:    my $msg = shift;
      871   0.29427   0.41000    67:    $$msg =~ /\G\{/gc;
      871   0.00177   0.00000    68:    my $h = {};
      871   0.29943   0.41000    69:    while ($$msg =~ 
/\G\s*(\S+?)\s*=\s*/gc) {
    10410   0.05206   0.29000    70: my $key = $1;
    10410   3.74933   3.80000    71: if ($$msg =~ /\G(?=\{)/gc) {
        0   0.00000   0.00000    72:     $h->{$key} = dict($msg);
        0   0.00000   0.00000    73:#     print "DICT $key => ", Dumper($h-
        0   0.00000   0.00000    74: } elsif ($$msg =~ /\G([^\|\}]*)/gc) {
     9541   0.03874   0.19000    75:     my $value = $1;
     9541   0.03370   0.17000    76:     $h->{$key} = $value;
        0   0.00000   0.00000    77:#     print "SCALAR $key => $value\n";
        0   0.00000   0.00000    78: }
    10410   0.34352   0.59000    79: return $h if $$msg =~ /\G\}/gc;
     9539   6.66969   6.42000    80: $$msg =~ /\G\|/gc;
        0   0.00000   0.00000    81:    }
        0   0.00000   0.00000    82:}

None of the PDU strings are tied or blessed. What's happening ? Please help!

Kind regards.

/ Jan Sundberg
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.