On Fri, Feb 19, 2010 at 04:19:50PM +0000, Tim Bunce wrote:

> Uh, yeah. I've been up to my neck in PostgreSQL/Safe stuff and haven't
> made much progress on  NYTProf. Guess we should get a release out the
> door before the land such a significant reorg.

Yes. :-)

As part of temptation, building on everything else I've done, I've just
made nytprofmerge take about 30% less time, by allowing the callback to
load_profile_data_from_file() to also be a hash reference.

For a hash reference, the tag name is looked up, with the value being a
callback subroutine to dispatch to. If there is no entry for the tag, a lookup
is made with an empty string key for a default subroutine. If there is no
default, then no callback is made for that tag.

Internally, in load_profile_to_callback() [doesn't exist yet on trunk],
it iterates over the hash when setting up the state, converting it to an array
of callback functions. This avoids all hash lookups at execution time.

Behaviour for a code reference is unchanged.

The diff for this for nytprofmerge is small, as I pretty much re-implemented
my existing dispatcher in XS:

diff --git a/bin/nytprofmerge b/bin/nytprofmerge
index 0fa4291..275d598 100755
--- a/bin/nytprofmerge
+++ b/bin/nytprofmerge
@@ -88,6 +88,9 @@ my $deflating;
 
 my %dispatcher =
     (
+     '' => sub {
+        die "Unknown tag '$_[0]' in $input\n";
+     },
      VERSION => sub {
         my (undef, $major, $minor) = @_;
         my $this_version = "$major $minor";
@@ -209,10 +212,9 @@ foreach $input (@ARGV) {
     @pending_fids = ();
     %pending_subs = ();
 
-    Devel::NYTProf::Data->new({filename => $input, callback => sub {
-       my $tag = shift;
-       if($tag eq 'NEW_FID') {
-           my ($fid, $eval_fid, $eval_line, $flags, $size, $mtime, $name) = @_;
+    Devel::NYTProf::Data->new({filename => $input, callback => {
+       NEW_FID => sub {
+           my (undef, $fid, $eval_fid, $eval_line, $flags, $size, $mtime, 
$name) = @_;
            my ($new_fid, $new_eval_fid);
            if($eval_fid) {
                # Generally, treat every eval as distinct, even at the same 
location
@@ -249,8 +251,9 @@ foreach $input (@ARGV) {
            }
            $fid_to_file{$new_fid} = $name;
            $pending_fids[$fid] = [$new_fid, $new_eval_fid];
-       } elsif ($tag eq 'SUB_INFO') {
-           my ($fid, $first_line, $last_line, $name) = @_;
+       },
+       SUB_INFO => sub {
+           my (undef, $fid, $first_line, $last_line, $name) = @_;
            my $output_fid;
            if ($name =~ $sub_is_anon_in_eval) {
                confess("No mapping for $fid") unless defined $fids{$fid};
@@ -289,11 +292,7 @@ foreach $input (@ARGV) {
     }});
 
     print "Re-reading $input...\n" if $opt_verbose;
-    Devel::NYTProf::Data->new({filename => $input, callback => sub {
-       my $sub = $dispatcher{$_[0]}
-            or die "Unknown tag '$_[0]' in $input\n";
-       &$sub(@_);
-    }});
+    Devel::NYTProf::Data->new({filename => $input, callback => \%dispatcher});
 }
 
 print "Finalizing...\n" if $opt_verbose;

[that's a diff from a state not yet on trunk either - it's been refactored
to avoid for_chunk, instead calling Devel::NYTProf::Data->new() directly.]

Of course, not even making a callback to Perl space when it's not wanted is
a big win, as is elimination of the second level subroutine call (as was).

Nicholas Clark

-- 
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.

Group hosted at:  http://groups.google.com/group/develnytprof-dev
Project hosted at:  http://perl-devel-nytprof.googlecode.com
CPAN distribution:  http://search.cpan.org/dist/Devel-NYTProf

To post, email:  [email protected]
To unsubscribe, email:  [email protected]

Reply via email to