Re: RE question...yup, another one ;)
by btrott (Parson) on May 26, 2001 at 23:26 UTC
|
Okay... well, since you don't want a direct answer, I will give
you an answer in a black box that you don't have to read, and
then I will give you a clue.
A regex is *way* too big a tool for this job.
print $_ % 10, "\n" for 0..300;
|
Here's your hint: think of a mathematical operator that might
do what you want here. It's in perlop, under
Multiplicative Operators. | [reply] [d/l] |
|
|
For the solution above, btrott, I believe you have it wrong. What happens when you get to 300? It prints 3000. Not the desired result; but I think I see where you are going with this. . . so here goes a quick attempt.
print $_ . "-->" . $_ % 10 for 0..300
| [reply] [d/l] |
|
|
| [reply] |
|
|
|
|
| [reply] |
japhy regex analysis: case study (RE question...)
by japhy (Canon) on May 27, 2001 at 08:41 UTC
|
use Benchmark 'timethese';
$x = int (1_000_000 * rand 1_000_000);
timethese(-5, {
multiple => sub { $x =~ /(\d)*(\d)/ },
backtrack_c => sub { $x =~ /(\d*)(\d)/ },
backtrack => sub { $x =~ /\d*(\d)/ },
opt => sub { $x =~ /(\d)$/ },
mod => sub { $x % 10 },
});
If snafu doesn't mind, I'd like to use this as an example in my book -- first to show how to craft a regex, then to show why there are some places where a regex is overkill.
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
|
Rate bt_c mult bt opt mod chop
bt_c 180870/s -- -1% -5% -28% -62% -74%
mult 181987/s 1% -- -4% -27% -62% -74%
bt 189426/s 5% 4% -- -24% -60% -73%
opt 249612/s 38% 37% 32% -- -48% -64%
mod 476214/s 163% 162% 151% 91% -- -31%
chop 692944/s 283% 281% 266% 178% 46% --
So chop is over 45% faster than mod even though it had
to make an extra copy of the string!
use Benchmark 'cmpthese';
$x = int (1_000_000 * rand 1_000_000);
cmpthese( -3, {
mult => sub { $x =~ /(\d)*(\d)/ },
bt_c => sub { $x =~ /(\d*)(\d)/ },
bt => sub { $x =~ /\d*(\d)/ },
opt => sub { $x =~ /(\d)$/ },
mod => sub { $x % 10 },
chop => sub { my $x= $x; chop $x },
});
Following are the original bogus results. Thanks to dkubb
for mentioning my over local. I realized I'd made a
mistake and came back but not quick enough. So it looks like
local is quite a bit slower than my (which makes
sense), so I'd be interested in how japhy's machine
compares the new code.
Rate mult bt_c bt opt mod chop
mult 180759/s -- -1% -7% -31% -62% -71%
bt_c 182581/s 1% -- -6% -31% -62% -70%
bt 193680/s 7% 6% -- -26% -60% -69%
opt 263234/s 46% 44% 36% -- -45% -57%
mod 481067/s 166% 163% 148% 83% -- -22%
chop 618559/s 242% 239% 219% 135% 29% --
So chop is almost 30% faster than mod even though it had
to make an extra copy of the string!
use Benchmark 'cmpthese';
$x = int (1_000_000 * rand 1_000_000);
cmpthese( -3, {
mult => sub { $x =~ /(\d)*(\d)/ },
bt_c => sub { $x =~ /(\d*)(\d)/ },
bt => sub { $x =~ /\d*(\d)/ },
opt => sub { $x =~ /(\d)$/ },
mod => sub { $x % 10 },
chop => sub { local $x; chop $x },
});
-
tye
(but my friends call me "Tye") | [reply] [d/l] [select] |
|
|
Even on a different machine, I get these results (the machine has the 5.005 version of Benchmark.pm):
timethese( -3, {
mod => sub { $x % 10 },
chop => sub { chop(my $x = $x) },
substr => sub { substr($x, -1) },
});
__END__
(they ran for at least 3 seconds)
chop: 8707.14/s (n= 29256)
substr: 43620.45/s (n=136532)
mod: 48906.87/s (n=163838)
So on my machine, mod is much faster than chop; the unexplored substr approach is nearly as fast.
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
|
|
|
|
|
Except that you never actually stored anything in local $x.
use Benchmark 'cmpthese';
$x = int (1_000_000 * rand 1_000_000);
cmpthese( -3, {
mod => sub { $x % 10 },
chop => sub { local $x; chop $x },
chop2 => sub { chop(local $x = $x) },
});
__END__
Rate chop2 chop mod
chop2 25430/s -- -88% -93%
chop 204396/s 704% -- -41%
mod 348051/s 1269% 70% --
On my machine, chop() was slower. But the real chop() approach was slower still.
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
|
Japhy,
Sure!! I would love it to be in your book. And I appreciate the thorough answer. I admit, the one thing I never even considered was the analogous nuts and bolts, hammers and wrenches of Perl.
Thanks!
----------
- Jim
| [reply] |
Re: RE question...yup, another one ;)
by nardo (Friar) on May 26, 2001 at 23:23 UTC
|
perl -e 'for ( $dec = 0 ; $dec <= 300 ; $dec++ ) {$dec =~ /(\d)$/ && print "$dec -> $1\n"; }' | [reply] [d/l] |
|
|
Wow, that was fast. I was actually about to say that I figured it out. But now, I notice my solution is a bit different from yours nardo. Which is better?
perl -e 'for ( $dec = 0 ; $dec <= 300 ; $dec++ ) { ($one = $dec) =~ s
+/(\d)+(\d)/$2/;print "$dec -> $one\n"; }'
----------
- Jim | [reply] [d/l] |
|
|
Which is better I suppose depends on personal style. Personally, I think that perl -e 'for (0..300) {print "$_ -> ", chop, "\n"; }'
is best, but the best approach using a regex is, in my opinion, perl -e 'for (0..300) {/(\d)$/ && print "$_ -> $1\n"; }' I think it's better style to use parenthesis inside a regex to match data and put it in $1 than it is to assign the whole thing to a new variable and then remove everything except what you want.
| [reply] [d/l] [select] |
|
|