In article <1p********************@comcast.com>, Bryan Krone
<br********@comcast.net> wrote:
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.