W
Wolfram Humann
I have a script for processing certain eps-files. What it basically does
is going through the file looking for "setgray"-lines. If it finds one,
it checks if it's followed by lines matching the values in @head and
then @dot (plus some coordinate-checks). If all matches, @head remains
in the file while @dot is discarded. If the match fails, the file
remains unchanged. Here is the script:
#!/usr/local/bin/perl -w
use strict;
my @head = (
'^N(\s+\d+)(\s+\d+)(\s+\d+) 0 360 arc sf N$',
'^\d+\s+slw$',
);
my @dot = (
'^(\d+)\s+(\d+)\s+M$',
('^(\d+)\s+(\d+)\s+D$') x 72,
);
my @c_head = map qr/$_/, @head;
my @c_dot = map qr/$_/, @dot;
my ($x, $y, $r);
while(<>)
{
print;
if(/^[0-9.]+\s+setgray\s+$/)
{
my ($h, $d) = (0,0);
my $l = "";
while(<>)
{
if ($head[$h])
{
print;
last unless $_ =~ $c_head[$h];
($x, $y, $r) = ($1, $2, $3) if defined $3;
$h++;
}
elsif ($dot[$d])
{
$l .= $_;
if ($_ !~ /$c_dot[$d]/ or
$1 < $x - $r - 2 or
$1 > $x + $r + 2 or
$2 < $y - $r - 2 or
$2 > $y + $r + 2 )
{
print $l;
last;
}
$d++;
}
else
{
print $l if /^\d+\s+\d+\s+D$/;
print;
last;
}
}
}
}
I was surprised how long it took and profiled with Devel::SmallProf.
This showed that most time is spent in "if (($_ !~ /$c_dot[$d]/) or...".
To see if the pattern match or the comparisons took so long, I split the
"if" like this:
if ($_ !~ /$c_dot[$d]/)
{
if ($1 < $x - $r - 2 or
$1 > $x + $r + 2 or
$2 < $y - $r - 2 or
$2 > $y + $r + 2 )
{
print $l;
last;
}
}
To my surprise a test run (without the profiler) ran *at least* twice as
fast as the original version. Also, the profiler says that "no time" is
spent for the comparisons and the time for the pattern match dropped to
one third of what is was before.
Any explanation?
Thanks,
Wolfram
is going through the file looking for "setgray"-lines. If it finds one,
it checks if it's followed by lines matching the values in @head and
then @dot (plus some coordinate-checks). If all matches, @head remains
in the file while @dot is discarded. If the match fails, the file
remains unchanged. Here is the script:
#!/usr/local/bin/perl -w
use strict;
my @head = (
'^N(\s+\d+)(\s+\d+)(\s+\d+) 0 360 arc sf N$',
'^\d+\s+slw$',
);
my @dot = (
'^(\d+)\s+(\d+)\s+M$',
('^(\d+)\s+(\d+)\s+D$') x 72,
);
my @c_head = map qr/$_/, @head;
my @c_dot = map qr/$_/, @dot;
my ($x, $y, $r);
while(<>)
{
print;
if(/^[0-9.]+\s+setgray\s+$/)
{
my ($h, $d) = (0,0);
my $l = "";
while(<>)
{
if ($head[$h])
{
print;
last unless $_ =~ $c_head[$h];
($x, $y, $r) = ($1, $2, $3) if defined $3;
$h++;
}
elsif ($dot[$d])
{
$l .= $_;
if ($_ !~ /$c_dot[$d]/ or
$1 < $x - $r - 2 or
$1 > $x + $r + 2 or
$2 < $y - $r - 2 or
$2 > $y + $r + 2 )
{
print $l;
last;
}
$d++;
}
else
{
print $l if /^\d+\s+\d+\s+D$/;
print;
last;
}
}
}
}
I was surprised how long it took and profiled with Devel::SmallProf.
This showed that most time is spent in "if (($_ !~ /$c_dot[$d]/) or...".
To see if the pattern match or the comparisons took so long, I split the
"if" like this:
if ($_ !~ /$c_dot[$d]/)
{
if ($1 < $x - $r - 2 or
$1 > $x + $r + 2 or
$2 < $y - $r - 2 or
$2 > $y + $r + 2 )
{
print $l;
last;
}
}
To my surprise a test run (without the profiler) ran *at least* twice as
fast as the original version. Also, the profiler says that "no time" is
spent for the comparisons and the time for the pattern match dropped to
one third of what is was before.
Any explanation?
Thanks,
Wolfram