Ok, I ran the benchmark, and it seems the regex form is faster. I have tested it several times with the following code and results:
use Parse::RecDescent;
use Date::Calc qw(:all);
use Benchmark ':all';
use strict;
use warnings;
my $grammar1 = q~
logic: expression eod
{ $return = $item[1]; }
expression: <leftop: term termop term>
termop: /and/i | /xor/i | /or/i
term: '(' <commit> expression ')'
{ $return = $item[3]; } #[@item[1,3,4]]; } # Only include eleme
+nts important to later processing
| condition
condition: element comparison element
{
$return = main::process(@item[1..3]);
}
element: '<' <commit> /-?\w+/ '>'
{ $return = "<$item[3]>"; } #Return this so that the conditio
+n value can be set
| /\d+/ # num is automatically returned
comparison: /(=[><]=)/ <commit> <error: Unable to match comparison,
+ $1>
| /=?[><]=?/
| '='
| '!='
eod: /^\Z/
~;
my $grammar2 = q~
logic: expression eod
{ $return = $item[1]; }
expression: <leftop: term termop term>
termop: /and/i | /xor/i | /or/i
term: '(' <commit> expression ')'
{ $return = $item[3]; } #[@item[1,3,4]]; } # Only include eleme
+nts important to later processing
| condition
condition: element comparison element
{
$return = main::process(@item[1..3]);
}
element: '<' <commit> /-?\w+/ '>'
{ $return = "<$item[3]>"; } #Return this so that the conditio
+n value can be set
| /\d+/ # num is automatically returned
comparison: '<=' | '<' | '=' | '>=' | '>' | '!='
eod: /^\Z/
~;
my $parser1 = new Parse::RecDescent($grammar1) or die;
my $parser2 = new Parse::RecDescent($grammar2) or die;
my $test = '<DAY> = 4 or <DAY> > 4 or <DAY> < 4 or <DAY> >= 4 or <DAY>
+ <= 4 or <DAY> != 4';
cmpthese(10000,{
'regex' => sub { $parser1->logic($test); },
'quote' => sub { $parser2->logic($test); },
});
Yielded:
Rate quote regex
quote 116/s -- -5%
regex 123/s 6% --
This one added the =>= which I wanted to avoid, and while it slowed down both slightly, the regex was still in the lead.
use Parse::RecDescent;
use Date::Calc qw(:all);
use Benchmark ':all';
use strict;
use warnings;
my $grammar1 = q~
logic: expression eod
{ $return = $item[1]; }
expression: <leftop: term termop term>
termop: /and/i | /xor/i | /or/i
term: '(' <commit> expression ')'
{ $return = $item[3]; } #[@item[1,3,4]]; } # Only include eleme
+nts important to later processing
| condition
condition: element comparison element
{
$return = main::process(@item[1..3]);
}
element: '<' <commit> /-?\w+/ '>'
{ $return = "<$item[3]>"; } #Return this so that the conditio
+n value can be set
| /\d+/ # num is automatically returned
comparison: /(=[><]=)/ <commit> <error: Unable to match comparison,
+ $1>
| /=?[><]=?/
| '='
| '!='
eod: /^\Z/
~;
my $grammar2 = q~
logic: expression eod
{ $return = $item[1]; }
expression: <leftop: term termop term>
termop: /and/i | /xor/i | /or/i
term: '(' <commit> expression ')'
{ $return = $item[3]; } #[@item[1,3,4]]; } # Only include eleme
+nts important to later processing
| condition
condition: element comparison element
{
$return = main::process(@item[1..3]);
}
element: '<' <commit> /-?\w+/ '>'
{ $return = "<$item[3]>"; } #Return this so that the conditio
+n value can be set
| /\d+/ # num is automatically returned
comparison: '<=' | '<' | '=' | '>=' | '>' | '!='
eod: /^\Z/
~;
my $parser1 = new Parse::RecDescent($grammar1) or die;
my $parser2 = new Parse::RecDescent($grammar2) or die;
my $test = '<DAY> = 4 or <DAY> > 4 or <DAY> < 4 or <DAY> >= 4 or <DAY>
+ <= 4 or <DAY> != 4 or <DAY> =<= 4';
cmpthese(10000,{
'regex' => sub { $parser1->logic($test); },
'quote' => sub { $parser2->logic($test); },
});
Yielded:
Rate quote regex
quote 104/s -- -7%
regex 113/s 8% --
I admit, neither is as fast as I would like, but it certainly appears that the regex is the fastest method there, unless I made a mistake.
Edit: If you feel this was biased in any way, feel free to suggest another string, or another test altogether. I don't use the benchmark module frequently, and I may have inadevertently allowed for some bias.
My code doesn't have bugs, it just develops random features.
Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN) |