Re: Speeding up recdescent...

[email protected] (Ted Zlatanov)
Newsgroups perl.recdescent
Organization Cienfuegos
Message-ID <[email protected]>
"Yves Orton" <[email protected]> writes:

> Over the weekend I started playing with Parse::RecDescent and decided
> to apply it to a real world problem. Now perhaps using a tool this
> powerful for what I want to do is gross overkill, but it seemed that
> using it resulted in less code that is more maintainable than hand
> rolling a parser. Seeing how much advice in the Monastery tends to
> argue that maintainable code is superior to faster code this route
> seemed ideal. Unfortunately using Parse::RecDescent is _much_ slower
> than I would like. So my question is threefold

> - Should I even be using Parse::RecDescent at all?

Yes, if you can wait for the C-optimized version of the module, which
Damian will release sometime in the future.

-or-

Yes, if your data format is likely to change, and you don't need to
parse the data quickly.

-or-

Yes, if you try the grammar without P:RD and decide it's not worth the
performance gains.  In your case, the grammar looks so simple that it
may be overkill to use P:RD.

> - Can I change the grammer to make it more efficient?

Avoid the type_t declaration with an optional regex, you should use

type_t      :   /ADD|ADDRANGE|DELETE|DELETERANGE/

or (even better)

ranged_type_t : /ADDRANGE|DELETERANGE/
simple_type_t : /ADD|DELETE/

and that will make the parsing simpler and faster.  But you're likely
to see small improvements from this and others.  P:RD is slower than a
specialized solution.

> - Are there any recommendations for what is in effect my first attempt
>   at using this very cool tool.

Look at the ways other people have used P:RD.  There's many examples
out there.

> The data (a file) that I need to parse looks like this:
>
> HDRCOMPNAME BIG000OLD111IDENTIFIER1020301WITH1010LOTS1010OF1010CRAP
> ADD,1234567890,,COMPNAME
> ADDRANGE,2468,4680,COMPNAME
> DELETE,987654321,,COMPNAME
> DELETERANGE,13579,13599,COMPNAME
> TLR000004
>
> and the grammer I am using looks like this:
>
> my $Grammar=<<'END_GRAMMAR';
>
> startrule   :   file
>
> file        :   header record(s?) trailer_t
>                 { $return={
>                            header=>$item[1],
>                            records=>$item[2],
>                            count=>$item[3]
>                           }
>                 }
>
> header      :   header_t data_t
>                 {
>                  $return={
>                           company=>$item[1],
>                           code=>$item[2]
>                          }
>                 }
>
> record      :   valid_rec | <error>
>
> valid_rec   :   type_t ',' number_t ',' number_t(?) ',' name_t
>                 { $return=[
>                            $item[1],
>                            $item[3],
>                            @{$item[5]} ? $item[5] : undef,
>                            $item[7]
>                           ]
>                 }
>
> header_t    :   /HDR\w+/ { $return=substr($item[1],3) }
> trailer_t   :   /TLR\d+/ { $return=substr($item[1],3) }
>
> data_t      :   /\w+/
> type_t      :   /ADD(?:RANGE)?|DELETE(?:RANGE)/
> number_t    :   /\d+/
> name_t      :   /\w+/
>
> END_GRAMMAR
>
> If its not obvious I have used the postfix _t for tokens.
> Any wisdom regarding this would be really appreciated. Especially if
> there is some way to modify the grammer to enhance speed. These files
> can contain thousands+ records and the speed hit is seriously making
> me think of hand rolling this (which I really really dont want to do).

-- 
Teodor Zlatanov <[email protected]>
"Brevis oratio penetrat colos, longa potatio evacuat ciphos." -Rabelais
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.