perl efficiency -- fastest grepping?

B

Bryan Krone

I have a stream of data comming off a serial port at 19200. I am wondering
what is the most efficient way to grep through the data in realtime? I have
20 or so different strings I need to find. All of which are ~15 characters
or less. Currently I'm using code that looks like this:

forever loop
{
sysread the serial buffer into $newdata

if( defined $newdata )
{
$inString =~ s/^.*(.{32})$/$1/o;
$inString .= $newdata;
}



if( $inString =~ /.*ResetPF.*/o || $inString =~ /.*[gG][oO].*/o || $inString
=~ /.*reset.*/o || $inString =~ /.*sysinit.*/o )
{
set some flag;
}
}
Is there a more efficient way to grep for the strings to set some flag? This
works pretty well but this is only 4 strings. I would like to add a lot
more but the program slows down after 10 or more strings. Any ideas would
be greatly appreciated.

Thanks
 
J

Jim Gibson

Bryan Krone said:
I have a stream of data comming off a serial port at 19200. I am wondering
what is the most efficient way to grep through the data in realtime? I have
20 or so different strings I need to find. All of which are ~15 characters
or less. Currently I'm using code that looks like this:

forever loop
{
sysread the serial buffer into $newdata

if( defined $newdata )
{
$inString =~ s/^.*(.{32})$/$1/o;
$inString .= $newdata;
}



if( $inString =~ /.*ResetPF.*/o || $inString =~ /.*[gG][oO].*/o || $inString
=~ /.*reset.*/o || $inString =~ /.*sysinit.*/o )
{
set some flag;
}
}
Is there a more efficient way to grep for the strings to set some flag? This
works pretty well but this is only 4 strings. I would like to add a lot
more but the program slows down after 10 or more strings. Any ideas would
be greatly appreciated.

The first thing to do is get rid of all the '.*' subpatterns. They do
nothing for your matching. In other words, /string/ will match whenever
/.*string.*/ matches. Wild cards can cause time-consuming backtracking.

If your patterns are all fixed strings, you are better off using the
index function instead of regular expressions. The only regular
expression you show above is /[gG][oO]/. You are probably better off
using the /i modifier to this regular expression and just searching for
/go/. You can also convert each input string to lower-case and use
index to search for 'go'.

Another suggestion, if you need to stick with REs, is to use alternate
patterns instead of separate searches. In other words,

$inString =~ /resetpf|go|reset|sysinit/i

may be faster than

($inString =~ /resetpf/i) || ($inString =~ /go/i) || ...

Use the Benchmark module to investigate how each of these suggestions
affects the speed of your program on your platform.

FYI: this newsgroup is defunct. Try comp.lang.perl.misc in the future.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top