Subject: | presentation2wire is slow, patches attached |
The presentation2wire method is somewhat slow.
Attached is a patch against 0.66 that includes a rewrite of it that I
believe is correct. If the patch won't apply, the replacement method is
included in presentation2wire.txt. 'make test' passes with this patch.
My benchmarks against it show that in most cases, the new code is
faster, excepting the case of a label of a single character:
mhorsfall@Fireforge:~/Development/NetDNS$ ./bm_p2w.pl
STRING: a.nl
Benchmark: timing 1000000 iterations of new, old...
new: 3 wallclock secs ( 4.02 usr + 0.00 sys = 4.02 CPU) @
248756.22/s (n=1000000)
old: 5 wallclock secs ( 3.86 usr + 0.00 sys = 3.86 CPU) @
259067.36/s (n=1000000)
STRING: a2.nl
Benchmark: timing 1000000 iterations of new, old...
new: 4 wallclock secs ( 3.97 usr + 0.00 sys = 3.97 CPU) @
251889.17/s (n=1000000)
old: 4 wallclock secs ( 4.96 usr + 0.00 sys = 4.96 CPU) @
201612.90/s (n=1000000)
STRING: test
Benchmark: timing 1000000 iterations of new, old...
new: 6 wallclock secs ( 4.94 usr + 0.00 sys = 4.94 CPU) @
202429.15/s (n=1000000)
old: 6 wallclock secs ( 6.14 usr + 0.00 sys = 6.14 CPU) @
162866.45/s (n=1000000)
STRING: test.com
Benchmark: timing 1000000 iterations of new, old...
new: 3 wallclock secs ( 4.11 usr + 0.00 sys = 4.11 CPU) @
243309.00/s (n=1000000)
old: 8 wallclock secs ( 7.20 usr + 0.00 sys = 7.20 CPU) @
138888.89/s (n=1000000)
STRING: www.test.com
Benchmark: timing 1000000 iterations of new, old...
new: 5 wallclock secs ( 4.02 usr + 0.01 sys = 4.03 CPU) @
248138.96/s (n=1000000)
old: 7 wallclock secs ( 6.13 usr + 0.00 sys = 6.13 CPU) @
163132.14/s (n=1000000)
STRING: exampleofalongdomainname.com
Benchmark: timing 1000000 iterations of new, old...
new: 5 wallclock secs ( 4.44 usr + 0.00 sys = 4.44 CPU) @
225225.23/s (n=1000000)
old: 28 wallclock secs (27.90 usr + 0.04 sys = 27.94 CPU) @
35790.98/s (n=1000000)
STRING: \.\@()h\\ello\.there\xAF\000there.com
Benchmark: timing 1000000 iterations of new, old...
new: 22 wallclock secs (22.74 usr + 0.01 sys = 22.75 CPU) @
43956.04/s (n=1000000)
old: 41 wallclock secs (40.60 usr + 0.02 sys = 40.62 CPU) @
24618.41/s (n=1000000)
I've included the benchmark code as well. The old method unpacked each
character individually (C1); the new method just treats the data as
text. If this is correct, I can work on wire2presentation next, and then
start messing around elsewhere. I just want the go ahead before I spend
too much more time doing this.
The code to handle backslashes is still a little slow, but I think this
is a step in the right direction.
Thanks.
-- alh
Subject: | bm_p2w.pl |
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Benchmark qw(timethese);
my @strings = qw(
a.nl
a2.nl
test
test.com
www.test.com
exampleofalongdomainname.com
\\.\\@()h\\\\ello\\.there\\xAF\\000there.com
);
for my $string (@strings) {
print "\nSTRING: $string\n";
timethese(1_000_000, {
'old' => sub { my ($f, $s) = old($string); },
'new' => sub { my ($f, $s) = new($string); },
});
}
sub new {
my $presentation=shift;
my $wire="";
while ($presentation =~ /\G([^.\\]*)([.\\]?)/g){
$wire .= $1 if defined $1;
if ($2) {
if ($2 eq '.') {
return ($wire,substr($presentation,pos $presentation));
}
#backslash found
if ($presentation =~ /\G(\d\d\d)/gc) {
$wire.=pack("C",$1);
} elsif ($presentation =~ /\Gx([0..9a..fA..F][0..9a..fA..F])/gc){
$wire.=pack("H*",$1);
} elsif ($presentation =~ /\G([@().\\])/gc){
$wire .= $1;
}
}
}
return $wire;
}
sub old {
my $presentation=shift;
my $wire="";
my $length=length($presentation);
my $i=0;
while ($i < $length ){
my $char=unpack("x".$i."C1",$presentation);
if ( $char == ord ('.')){
return ($wire,substr($presentation,$i+1));
}
if ( $char == ord ('\\')){
#backslash found
pos($presentation)=$i+1;
if ($presentation=~/\G(\d\d\d)/){
$wire.=pack("C",$1);
$i+=3;
}elsif($presentation=~/\Gx([0..9a..fA..F][0..9a..fA..F])/){
$wire.=pack("H*",$1);
$i+=3;
}elsif($presentation=~/\G\./){
$wire.="\.";
$i+=1;
}elsif($presentation=~/\G@/){
$wire.="@";
$i+=1;
}elsif($presentation=~/\G\(/){
$wire.="(";
$i+=1;
}elsif($presentation=~/\G\)/){
$wire.=")";
$i+=1;
}elsif($presentation=~/\G\\/){
$wire.="\\";
$i+=1;
}
}else{
$wire .= pack("C",$char);
}
$i++;
}
return $wire;
}
Subject: | presentation2wire.txt |
sub presentation2wire {
my $presentation=shift;
my $wire="";
while ($presentation =~ /\G([^.\\]*)([.\\]?)/g){
$wire .= $1 if defined $1;
if ($2) {
if ($2 eq '.') {
return ($wire,substr($presentation,pos $presentation));
}
#backslash found
if ($presentation =~ /\G(\d\d\d)/gc) {
$wire.=pack("C",$1);
} elsif ($presentation =~ /\Gx([0..9a..fA..F][0..9a..fA..F])/gc){
$wire.=pack("H*",$1);
} elsif ($presentation =~ /\G([@().\\])/gc){
$wire .= $1;
}
}
}
return $wire;
}
Subject: | presentation2wire.patch.txt |
diff -ur Net-DNS-0.66/lib/Net/DNS.pm Net-DNS-0.66-fast/lib/Net/DNS.pm
--- Net-DNS-0.66/lib/Net/DNS.pm 2009-12-30 06:01:39.000000000 -0500
+++ Net-DNS-0.66-fast/lib/Net/DNS.pm 2011-04-11 20:40:27.000000000 -0400
@@ -492,44 +492,24 @@
sub presentation2wire {
my $presentation=shift;
my $wire="";
- my $length=length($presentation);
- my $i=0;
-
- while ($i < $length ){
- my $char=unpack("x".$i."C1",$presentation);
- if ( $char == ord ('.')){
- return ($wire,substr($presentation,$i+1));
- }
- if ( $char == ord ('\\')){
- #backslash found
- pos($presentation)=$i+1;
- if ($presentation=~/\G(\d\d\d)/){
- $wire.=pack("C",$1);
- $i+=3;
- }elsif($presentation=~/\Gx([0..9a..fA..F][0..9a..fA..F])/){
- $wire.=pack("H*",$1);
- $i+=3;
- }elsif($presentation=~/\G\./){
- $wire.="\.";
- $i+=1;
- }elsif($presentation=~/\G@/){
- $wire.="@";
- $i+=1;
- }elsif($presentation=~/\G\(/){
- $wire.="(";
- $i+=1;
- }elsif($presentation=~/\G\)/){
- $wire.=")";
- $i+=1;
- }elsif($presentation=~/\G\\/){
- $wire.="\\";
- $i+=1;
+ while ($presentation =~ /\G([^.\\]*)([.\\]?)/g){
+ $wire .= $1 if defined $1;
+
+ if ($2) {
+ if ($2 eq '.') {
+ return ($wire,substr($presentation,pos $presentation));
}
- }else{
- $wire .= pack("C",$char);
+
+ #backslash found
+ if ($presentation =~ /\G(\d\d\d)/gc) {
+ $wire.=pack("C",$1);
+ } elsif ($presentation =~ /\Gx([0..9a..fA..F][0..9a..fA..F])/gc){
+ $wire.=pack("H*",$1);
+ } elsif ($presentation =~ /\G([@().\\])/gc){
+ $wire .= $1;
+ }
}
- $i++;
}
return $wire;
Only in Net-DNS-0.66-fast/: Makefile.old