Skip Menu |

This queue is for tickets about the Net-DNS CPAN distribution.

Report information
The Basics
Id: 67418
Status: resolved
Priority: 0/
Queue: Net-DNS

People
Owner: Nobody in particular
Requestors: WolfSage [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.66
Fixed in: (no value)



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
Sending the previous mail has failed. Please contact your admin, they can find more details in the logs.
Sending the previous mail has failed. Please contact your admin, they can find more details in the logs.
Hi Matt, Very nice work. Thank you! I especially like the fact that the presentation is now handled as character strings in stead of byte strings. Looking forward to your coming patches :) Best regards, Willem