Author: tim.bunce
Date: Sat Nov  8 15:03:28 2008
New Revision: 591

Modified:
    trunk/Changes
    trunk/HACKING
    trunk/bin/nytprofcsv
    trunk/bin/nytprofhtml
    trunk/lib/Devel/NYTProf/Reader.pm

Log:
Removed column handling from Devel::NYTProf::Reader module,
it's now just concerned with files and lines.
A single callback per line improves performance and flexibility.
Statement timings are now shown formatted with units.


Modified: trunk/Changes
==============================================================================
--- trunk/Changes       (original)
+++ trunk/Changes       Sat Nov  8 15:03:28 2008
@@ -6,6 +6,10 @@

  =head2 Changes in Devel::NYTProf 2.08

+  Dramatically increased performance of nytprofhtml
+    relative to the 2.07 version.
+  Statement timings are now shown as integers in appropriate
+    units: seconds, milliseconds, microseconds or nanoseconds.
    Improved HTML conformance thanks to Leland Johnson.

  =head2 Changes in Devel::NYTProf 2.07 (svn r583) 1st Nov 2008

Modified: trunk/HACKING
==============================================================================
--- trunk/HACKING       (original)
+++ trunk/HACKING       Sat Nov  8 15:03:28 2008
@@ -318,3 +318,7 @@
  a package where a lot of time is being spent in lots of different subs.

  Add option to set processor affinity.
+
+Trace level 1 should show totals fids, subs etc.
+
+Index should show eval fids in some form - collapsed per location?

Modified: trunk/bin/nytprofcsv
==============================================================================
--- trunk/bin/nytprofcsv        (original)
+++ trunk/bin/nytprofcsv        Sat Nov  8 15:03:28 2008
@@ -61,8 +61,18 @@
  # place to store this
  $reporter->output_dir($opt{out});

-# set output options
-$reporter->add_regexp('^\s*', '');    # trim leading spaces
+$reporter->set_param(mk_report_source_line => sub {
+    my ($linenum, $line, $stats_for_line, $statistics, $subs_defined,  
$makes_calls_to, $profile, $filestr) = @_;
+    $line =~ s/^\s*//; # trim leading spaces
+    return sprintf("%f,%g,%f,%s\n",
+        $stats_for_line->{'time'} || 0,
+        $stats_for_line->{'calls'} || 0,
+        $stats_for_line->{'time/call'} || 0,
+        $line,
+    );
+});
+
+$reporter->set_param(mk_report_xsub_line => sub { "" });

  # generate the files
  $reporter->report();

Modified: trunk/bin/nytprofhtml
==============================================================================
--- trunk/bin/nytprofhtml       (original)
+++ trunk/bin/nytprofhtml       Sat Nov  8 15:03:28 2008
@@ -193,11 +193,11 @@

          $sub_links .= "<tr>";

-        $sub_links .= determine_severity(undef, $sub->calls        || 0,  
$dev_calls);
-        $sub_links .= determine_severity(undef, $sub->caller_count || 0,  
$dev_call_count);
-        $sub_links .= determine_severity(undef, $sub->caller_fids  || 0,  
$dev_call_fids);
-        $sub_links .= determine_severity(undef, $sub->excl_time    || 0,  
$dev_excl_time);
-        $sub_links .= determine_severity(undef, $sub->incl_time    || 0,  
$dev_incl_time);
+        $sub_links .= determine_severity($sub->calls        || 0,  
$dev_calls);
+        $sub_links .= determine_severity($sub->caller_count || 0,  
$dev_call_count);
+        $sub_links .= determine_severity($sub->caller_fids  || 0,  
$dev_call_fids);
+        $sub_links .= determine_severity($sub->excl_time    || 0,  
$dev_excl_time, 1);
+        $sub_links .= determine_severity($sub->incl_time    || 0,  
$dev_incl_time, 1);

          # package and subname
          my $subname = $sub->subname;
@@ -254,123 +254,134 @@
      }
  );

-$reporter->set_param(
-    'linestart',
-    {   func => sub {
-            my ($value, $linenum, $linesrc) = @_;
-            (my $anchor = defined($linenum) ? $linenum : $value) =~  
s/\W/_/g;
-            sprintf qq{<tr><td class="h"><a name="%s"></a>%s</td>},  
$anchor, $linenum;
-        },
-    }
-);
+$reporter->set_param(mk_report_source_line => \&mk_report_source_line);
+$reporter->set_param(mk_report_xsub_line   => \&mk_report_xsub_line  );

+sub mk_report_source_line {
+    my ($linenum, $line, $stats_for_line, $stats_for_file, $subs_defined,  
$makes_calls_to, $profile, $filestr) = @_;

-$reporter->set_param('column1', {value => 'calls',     func =>  
\&determine_severity});
-$reporter->set_param('column2', {value => 'time',      func =>  
\&determine_severity});
-$reporter->set_param('column3', {value => 'time/call', func =>  
\&determine_severity});
+    my $l = sprintf(qq{<td class="h"><a name="%s"></a>%s</td>}, $linenum,  
$linenum);
+    my $s = report_src_line(undef, $linenum, $line, $profile,  
$subs_defined, $makes_calls_to, $filestr);

-$reporter->set_param(
-    'column4',
-    {   func => sub {
-            my ($value, $linenum, $linesrc, $profile, $subs, $calls,  
$thisfile) = @_;
-
-            $linesrc =~ s/&/&amp;/g;
-            $linesrc =~ s/</&lt;/g;
-            $linesrc =~ s/>/&gt;/g;
-            $linesrc =~ s/\t/        /g;
-            $linesrc =~ s{\n}{<br />}g; # for xsub pseudo-sub declarations
-
-            my @prologue;
-
-            # for each of the subs defined on this line, who called them
-            for my $sub_info (@$subs) {
-                my $callers = $sub_info->callers;
-                next unless $callers && %$callers;
-
-                my @callers;
-                while (my ($fid, $fid_line_info) = each %$callers) {
-                    push @callers, [$fid, $_, @{$fid_line_info->{$_}}] for  
keys %$fid_line_info;
-                }
-                my $total_calls = sum(my @caller_calls = map { $_->[2] }  
@callers);
-                my $max_calls = max(@caller_calls);
-                my $avg_per_call = fmt_time($sub_info->incl_time /  
$total_calls);
-
-                push @prologue, sprintf "# spent %s within %s which was  
called%s",
-                    fmt_incl_excl_time($sub_info->incl_time,  
$sub_info->excl_time),
-                    $sub_info->subname, ($total_calls <= 1)
-                    ? ""
-                    : " $total_calls times, avg ${avg_per_call}/call:";
-
-                # order by most frequent caller first
-                @callers = sort { $b->[2] <=> $a->[2] || $b->[3] <=>  
$a->[3] } @callers;
-                for my $caller (@callers) {
-                    my ($fid, $line, $count, $incl_time, $excl_time) =  
@$caller;
-                    my $fi = $profile->fileinfo_of($fid);
-
-                    my @subnames = $profile->subname_at_file_line($fid,  
$line);
-                    my $subname = (@subnames) ? " by " . join(" or ",  
@subnames) : "";
-                    my $avg_time =
-                        ($count <= 1)
-                        ? ""
-                        : sprintf ", avg %s/call", fmt_time($incl_time /  
$count);
-                    my $times = sprintf " (%s+%s)", fmt_time($excl_time),
-                        fmt_time($incl_time - $excl_time);
-
-                    my $filename = $fi->filename($fid);
-                    my $line_desc = "line $line of $filename";
-                    # chase string eval chain back to a real file
-                    while ( my ($outer_fileinfo, $outer_line) = $fi->outer  
) {
-                        ($filename, $line) = ($outer_fileinfo->filename,  
$outer_line);
-                        $line_desc .= sprintf " at line %s of %s", $line,  
$filename;
-                        $fi = $outer_fileinfo;
-                    }
+    return "<tr>$l<td></td><td></td><td></td>$s</tr>\n"
+        if not %$stats_for_line;
+
+    return join "",
+        "<tr>$l",
+        determine_severity($stats_for_line->{'calls'},      
$stats_for_file->{'calls'}),
+        determine_severity($stats_for_line->{'time'},       
$stats_for_file->{'time'}, 1),
+        determine_severity($stats_for_line->{'time/call'},  
$stats_for_file->{'time/call'}, 1),
+        $s, "</tr>\n";
+}

-                    my $href =  
$reporter->get_file_stats()->{$filename}{html_safe} || "unknown";
-                    $line_desc =~ s/ of $filename$// if $filename eq  
$thisfile;
+sub mk_report_xsub_line {
+    my ($subname, $line, $stats_for_line, $stats_for_file, $subs_defined,  
$makes_calls_to, $profile, $filestr) = @_;
+    (my $anchor = $subname) =~ s/\W/_/g;
+    return join "",
+        sprintf(qq{<tr><td class="h"><a name="%s"></a>%s</td>},  
$anchor, ''),
+        "<td></td><td></td><td></td>",
+        report_src_line(undef, undef, $line, $profile, $subs_defined,  
$makes_calls_to, $filestr),
+        "</tr>\n";
+}

-                    push @prologue,
-                        sprintf q{# %*s times%s%s at <a  
href="%s#%d">%s</a>%s},
-                        length($max_calls), $count, $times,  
$subname, "$href.html", $line,
-                        $line_desc, $avg_time;
-                   $prologue[-1] =~ s/^(# +)1 times/$1   once/;  # better 
English
-                }
-            }
-            my $prologue = '';
-            $prologue = sprintf qq{<div class="calls"><div  
class="calls_in">%s</div></div>}, join("\n", @prologue)
-                if @prologue;
-
-            # give details of each of the subs called by this line
-            my $epilogue = '';
-            if (%$calls) {
-
-                my @calls_to = sort {
-                    $calls->{$b}[1] <=> $calls->{$a}[1] or    # incl_time
-                        $a cmp $b
-                } keys %$calls;
-                my $max_calls_to = max(map { $_->[0] } values %$calls);
-                my $ws = ($linesrc =~ m/^((?:&nbsp;|\s)+)/) ? $1 : '';
-
-                $epilogue = join "\n", map {
-                    my ($count, $incl_time, $reci_time, $rec_depth) =  
(@{$calls->{$_}})[0,1,5,6];
-                    my $html = sprintf qq{%s# spent %s making %*d call%s  
to }, $ws,
-                        fmt_time($incl_time+$reci_time, 5),  
length($max_calls_to),
-                       $count, $count == 1 ? "" : "s";
-                    $html .= sprintf qq{<a %s>%s</a>},  
$reporter->href_for_sub($_), $_;
-                    $html .= sprintf qq{, avg %s/call},  
fmt_time($incl_time / $count)
-                        if $count > 1;
-                    $html .= sprintf qq{, max recursion depth %d},  
$rec_depth
-                        if $rec_depth;
-                    $html;
-                } @calls_to;
-                $epilogue = sprintf qq{<div class="calls"><div  
class="calls_out">%s</div></div>}, $epilogue;
+
+sub report_src_line {
+    my ($value, undef, $linesrc, $profile, $subs, $calls, $thisfile) = @_;
+
+    $linesrc =~ s/&/&amp;/g;
+    $linesrc =~ s/</&lt;/g;
+    $linesrc =~ s/>/&gt;/g;
+    $linesrc =~ s/\t/        /g;
+    $linesrc =~ s{\n}{<br />}g; # for xsub pseudo-sub declarations
+
+    my @prologue;
+
+    # for each of the subs defined on this line, who called them
+    for my $sub_info (@$subs) {
+        my $callers = $sub_info->callers;
+        next unless $callers && %$callers;
+
+        my @callers;
+        while (my ($fid, $fid_line_info) = each %$callers) {
+            push @callers, [$fid, $_, @{$fid_line_info->{$_}}] for  
keys %$fid_line_info;
+        }
+        my $total_calls = sum(my @caller_calls = map { $_->[2] } @callers);
+        my $max_calls = max(@caller_calls);
+        my $avg_per_call = fmt_time($sub_info->incl_time / $total_calls);
+
+        push @prologue, sprintf "# spent %s within %s which was called%s",
+            fmt_incl_excl_time($sub_info->incl_time, $sub_info->excl_time),
+            $sub_info->subname, ($total_calls <= 1)
+            ? ""
+            : " $total_calls times, avg ${avg_per_call}/call:";
+
+        # order by most frequent caller first
+        @callers = sort { $b->[2] <=> $a->[2] || $b->[3] <=> $a->[3] }  
@callers;
+        for my $caller (@callers) {
+            my ($fid, $line, $count, $incl_time, $excl_time) = @$caller;
+            my $fi = $profile->fileinfo_of($fid);
+
+            my @subnames = $profile->subname_at_file_line($fid, $line);
+            my $subname = (@subnames) ? " by " . join(" or ",  
@subnames) : "";
+            my $avg_time =
+                ($count <= 1)
+                ? ""
+                : sprintf ", avg %s/call", fmt_time($incl_time / $count);
+            my $times = sprintf " (%s+%s)", fmt_time($excl_time),
+                fmt_time($incl_time - $excl_time);
+
+            my $filename = $fi->filename($fid);
+            my $line_desc = "line $line of $filename";
+            # chase string eval chain back to a real file
+            while ( my ($outer_fileinfo, $outer_line) = $fi->outer ) {
+                ($filename, $line) = ($outer_fileinfo->filename,  
$outer_line);
+                $line_desc .= sprintf " at line %s of %s", $line,  
$filename;
+                $fi = $outer_fileinfo;
              }

-            sprintf qq{<td class="s">%s%s%s</td>}, $prologue, $linesrc,  
$epilogue;
-        },
+            my $href = $reporter->get_file_stats()->{$filename}{html_safe}  
|| "unknown";
+            $line_desc =~ s/ of $filename$// if $filename eq $thisfile;
+
+            push @prologue,
+                sprintf q{# %*s times%s%s at <a href="%s#%d">%s</a>%s},
+                length($max_calls), $count, $times,  
$subname, "$href.html", $line,
+                $line_desc, $avg_time;
+            $prologue[-1] =~ s/^(# +)1 times/$1   once/;  # better English
+        }
      }
-);
+    my $prologue = '';
+    $prologue = sprintf qq{<div class="calls"><div  
class="calls_in">%s</div></div>}, join("\n", @prologue)
+        if @prologue;
+
+    # give details of each of the subs called by this line
+    my $epilogue = '';
+    if (%$calls) {
+
+        my @calls_to = sort {
+            $calls->{$b}[1] <=> $calls->{$a}[1] or    # incl_time
+                $a cmp $b
+        } keys %$calls;
+        my $max_calls_to = max(map { $_->[0] } values %$calls);
+        my $ws = ($linesrc =~ m/^((?:&nbsp;|\s)+)/) ? $1 : '';
+
+        $epilogue = join "\n", map {
+            my ($count, $incl_time, $reci_time, $rec_depth) =  
(@{$calls->{$_}})[0,1,5,6];
+            my $html = sprintf qq{%s# spent %s making %*d call%s to }, $ws,
+                fmt_time($incl_time+$reci_time, 5), length($max_calls_to),
+                $count, $count == 1 ? "" : "s";
+            $html .= sprintf qq{<a %s>%s</a>},  
$reporter->href_for_sub($_), $_;
+            $html .= sprintf qq{, avg %s/call}, fmt_time($incl_time /  
$count)
+                if $count > 1;
+            $html .= sprintf qq{, max recursion depth %d}, $rec_depth
+                if $rec_depth;
+            $html;
+        } @calls_to;
+        $epilogue = sprintf qq{<div class="calls"><div  
class="calls_out">%s</div></div>}, $epilogue;
+    }
+
+    return qq{<td class="s">$prologue$linesrc$epilogue</td>};
+}

-$reporter->set_param('lineend', { func => sub { "</tr>\n" } });

  # set output options
  $reporter->set_param('suffix', '.html');
@@ -565,8 +576,8 @@
      foreach my $filestats (sort { $b->{'time'} <=> $a->{'time'} }  
values %$stats) {
          print OUT qq{<tr class="index">};
          print OUT qq{<td class="n">$filestats->{calls}</td>};
-        print OUT determine_severity('time',       
$filestats->{'time'},      $dev_time);
-        print OUT determine_severity('time/call',  
$filestats->{'time/call'}, $dev_avgt);
+        print OUT determine_severity($filestats->{'time'},      $dev_time,  
1);
+        print OUT determine_severity($filestats->{'time/call'}, $dev_avgt,  
1);

          my $rep_links = join '&nbsp;&bull;&nbsp;', map {
              my $level_html_safe = $filestats->{$_}->{html_safe};
@@ -590,11 +601,11 @@
      if ($add_totals) {
          my $stats_fmt =
              qq{<tr class="index"><td class="n">%s</td><td  
class="n">%s</td><td class="n">%s</td><td colspan="2" style="font-style:  
italic">%s</td></tr>};
-        print OUT sprintf $stats_fmt, fmt_float($allCalls),  
fmt_float($allTimes), '', "Total";
+        print OUT sprintf $stats_fmt, fmt_float($allCalls),  
fmt_time($allTimes), '', "Total";
          print OUT sprintf $stats_fmt, int(fmt_float($allCalls /  
keys %$stats)),
-            fmt_float($allTimes / keys %$stats), '', "Average"
+            fmt_time($allTimes / keys %$stats), '', "Average"
              if %$stats;    # avoid divide by zero
-        print OUT sprintf $stats_fmt, '', fmt_float($dev_time->[1]),  
fmt_float($dev_avgt->[1]),
+        print OUT sprintf $stats_fmt, '', fmt_time($dev_time->[1]),  
fmt_time($dev_avgt->[1]),
              "Median";
          print OUT sprintf $stats_fmt, '', fmt_float($dev_time->[0]),  
fmt_float($dev_avgt->[0]),
              "Deviation";
@@ -606,12 +617,16 @@

  # calculates how good or bad the time is for a file based on the others
  sub determine_severity {
-    my (undef, $val, $stats) = @_;    # @_[3] is like arrayref (deviation,  
mean)
+    my $val = shift;
      return "<td></td>" unless defined $val;
+    my $stats = shift;    # @_[3] is like arrayref (deviation, mean)
+    my $is_time = shift;

      # normalize the width/precision so that the tables look good.
-    $val = fmt_float($val, NUMERIC_PRECISION);
-    return qq{<td class="n">$val</td>} unless defined $stats;
+    my $fmt_val = ($is_time)
+        ? fmt_time($val)
+        : fmt_float($val, NUMERIC_PRECISION);
+    return qq{<td class="n">$fmt_val</td>} unless defined $stats;

      my $devs = ($val - $stats->[1]);    #stats->[1] is the mean.
      $devs /= $stats->[0] if $stats->[0];    # no divide by zero when all  
values equal
@@ -632,7 +647,7 @@
      else {
          $class = 'c0';
      }
-    return qq{<td class="$class">$val</td>};
+    return qq{<td class="$class">$fmt_val</td>};
  }

  # Delete the previous database/directory if it exists

Modified: trunk/lib/Devel/NYTProf/Reader.pm
==============================================================================
--- trunk/lib/Devel/NYTProf/Reader.pm   (original)
+++ trunk/lib/Devel/NYTProf/Reader.pm   Sat Nov  8 15:03:28 2008
@@ -50,6 +50,8 @@
              . "# More information at  
http://search.cpan.org/dist/Devel-NYTProf/\n";
              . "# Format: time,calls,time/call,code\n",
          datastart => '',
+        mk_report_source_line => undef,
+        mk_report_xsub_line   => undef,
          line      => [
              {},
              {value => 'time',      end => ',', default => '0'},
@@ -73,22 +75,22 @@
                  replace => "\$LEVEL"
              },
              {   pattern => '!~DEV_CALLS~!',
-                replace => "\$statistics{calls}->[0]"
+                replace => "\$stats_for_file{calls}->[0]"
              },
              {   pattern => '!~DEV_TIME~!',
-                replace => "\$statistics{time}->[0]"
+                replace => "\$stats_for_file{time}->[0]"
              },
              {   pattern => '!~DEV_TIME/CALL~!',
-                replace => "\$statistics{'time/calls'}"
+                replace => "\$stats_for_file{'time/calls'}"
              },
              {   pattern => '!~MEAN_CALLS~!',
-                replace => "\$statistics{calls}->[1]"
+                replace => "\$stats_for_file{calls}->[1]"
              },
              {   pattern => '!~MEAN_TIME~!',
-                replace => "\$statistics{time}->[1]"
+                replace => "\$stats_for_file{time}->[1]"
              },
              {   pattern => '!~MEAN_TIME/CALLS~!',
-                replace => "\$statistics{'time/calls'}->[1]"
+                replace => "\$stats_for_file{'time/calls'}->[1]"
              },
              {   pattern => '!~TOTAL_CALLS~!',
                  replace => "\$self->{filestats}->{\$filestr}->{'calls'}"
@@ -171,25 +173,7 @@
  sub set_param {
      my ($self, $param, $value) = @_;

-    if ($param eq 'linestart') {
-        $self->{line}->[0] = $value;
-    }
-    elsif ($param eq 'column1') {
-        $self->{line}->[1] = $value;
-    }
-    elsif ($param eq 'column2') {
-        $self->{line}->[2] = $value;
-    }
-    elsif ($param eq 'column3') {
-        $self->{line}->[3] = $value;
-    }
-    elsif ($param eq 'column4') {
-        $self->{line}->[4] = $value;
-    }
-    elsif ($param eq 'lineend') {
-        $self->{line}->[5] = $value;
-    }
-    elsif (!exists $self->{$param}) {
+    if (!exists $self->{$param}) {
          confess "Attempt to set $param to $value failed: $param is not a  
valid " . "parameter\n";
      }
      else {
@@ -211,12 +195,6 @@
  }

  ##
-sub add_regexp {
-    my ($self, $pattern, $replace) = @_;
-    push(@{$self->{user_regexp}}, {pattern => $pattern, replace =>  
$replace});
-}
-
-##
  sub file_has_been_modified {
      my $self = shift;
      my $file = shift;
@@ -236,8 +214,7 @@

  ##
  sub get_file_stats {
-    my $self = shift;
-    return $self->{filestats};
+    return shift->{filestats};
  }

  ##
@@ -309,11 +286,11 @@
          # file might differ from what it looked like before.
          my $tainted = $self->file_has_been_modified($filestr);

-        my %totalsAccum;         # holds all line times. used to find  
median
-        my %totalsByLine;        # holds individual line stats
+        my %stats_accum;         # holds all line times. used to find  
median
+        my %stats_by_line;        # holds individual line stats
          my $runningTotalTime = 0;  # holds the running total

-        # (should equal sum of $totalsAccum)
+        # (should equal sum of $stats_accum)
          my $runningTotalCalls = 0; # holds the running total number of  
calls.

          # note that a file may have no source lines executed, so no keys  
here
@@ -340,14 +317,14 @@
                  # as that would be inappropriate and misleading
                  $time += $_->[0] for values %$eval_lines;
              }
-            push(@{$totalsAccum{'time'}},      $time);
-            push(@{$totalsAccum{'calls'}},     $a->[1]);
-            push(@{$totalsAccum{'time/call'}}, $time / $a->[1]);
-
-            $totalsByLine{$key}->{'time'}  += $time;
-            $totalsByLine{$key}->{'calls'} += $a->[1];
-            $totalsByLine{$key}->{'time/call'} =
-                $totalsByLine{$key}->{'time'} /  
$totalsByLine{$key}->{'calls'};
+            push(@{$stats_accum{'time'}},      $time);
+            push(@{$stats_accum{'calls'}},     $a->[1]);
+            push(@{$stats_accum{'time/call'}}, $time / $a->[1]);
+
+            $stats_by_line{$key}->{'time'}  += $time;
+            $stats_by_line{$key}->{'calls'} += $a->[1];
+            $stats_by_line{$key}->{'time/call'} =
+                $stats_by_line{$key}->{'time'} /  
$stats_by_line{$key}->{'calls'};

              $runningTotalTime  += $time;
              $runningTotalCalls += $a->[1];
@@ -360,10 +337,10 @@

          # Use Median Absolute Deviation Formula to get file deviations for  
each of
          # calls, time and time/call values
-        my %statistics = (
-            'calls'     =>  
calculate_median_absolute_deviation($totalsAccum{'calls'}||[]),
-            'time'      =>  
calculate_median_absolute_deviation($totalsAccum{'time'}||[]),
-            'time/call' =>  
calculate_median_absolute_deviation($totalsAccum{'time/call'}||[]),
+        my %stats_for_file = (
+            'calls'     =>  
calculate_median_absolute_deviation($stats_accum{'calls'}||[]),
+            'time'      =>  
calculate_median_absolute_deviation($stats_accum{'time'}||[]),
+            'time/call' =>  
calculate_median_absolute_deviation($stats_accum{'time/call'}||[]),
          );

          my $line_calls_hash = $profile->line_calls_for_file($filestr, 1);
@@ -430,98 +407,40 @@
              $LINE = 0;
          }

+        my $line_sub = $self->{mk_report_source_line}
+            or die "mk_report_source_line not set";
+
          while ( my $line = shift @$src_lines ) {
              chomp $line;
-            foreach my $regexp (@{$self->{user_regexp}}) {
-                $line =~ s/$regexp->{pattern}/$regexp->{replace}/g;
-            }
+
              if ($line =~ m/^\# \s* line \s+ (\d+) \b/x) {
                  # XXX we should be smarter about this - patches welcome!
                  warn "Ignoring '$line' directive at line $LINE - profile  
data for $filestr will be out of sync with source!\n"
                      unless our $line_directive_warn->{$filestr}++; # once  
per file
              }
+
              my $makes_calls_to = $line_calls_hash->{$LINE}   || {};
              my $subs_defined   = $subs_defined_hash->{$LINE} || [];
+            my $stats_for_line = $stats_by_line{$LINE} || {};

-            # begin output
-
-            foreach my $hash (@{$self->{line}}) {
-
-                # If a func reference is provided, it will control output  
for this column.
-                if (defined(my $func = $hash->{func})) {
-                    my $value = $hash->{value};
-                    if ($value) {
-                        print OUT $func->(
-                            $value, $totalsByLine{$LINE}->{$value},
-                            $statistics{$value}, $LINE, $line, $profile,  
$subs_defined,
-                            $makes_calls_to, $filestr
-                        );
-                    }
-                    else {
-                        print OUT $func->(
-                            $value, $LINE, $line, $profile, $subs_defined,  
$makes_calls_to, $filestr
-                        );
-                    }
-                    next;
-                }
-
-                print OUT $hash->{start} if defined $hash->{start};
-                if (defined $hash->{value}) {
-                    if ($hash->{value} eq 'source') {
-                        print OUT $line;    # from source rather than  
profile db
-                    }
-                    elsif ($hash->{value} eq 'line') {
-                        print OUT $LINE;
-                    }
-                    elsif (exists $data->{$filestr}->{$LINE}) {
-                        printf(OUT "%0."
-                                .  
$self->{numeric_precision}->{$hash->{value}}
-                                . $FLOAT_FORMAT,
-                            $totalsByLine{$LINE}->{$hash->{value}}
-                        );
-                    }
-                    else {
-                        print OUT $hash->{default};
-                    }
-                }
-                print OUT $hash->{end} if defined $hash->{end};
-            }
-
+            print OUT $line_sub->($LINE, $line, $stats_for_line,  
\%stats_for_file, $subs_defined, $makes_calls_to, $profile, $filestr);
          }
          continue {
-
              # Increment line number counters
              $LINE++;
          }

          # iterate over xsubs
+        $line_sub = $self->{mk_report_xsub_line}
+            or die "mk_report_xsub_line not set";
          my $subs_defined_in_file =  
$profile->subs_defined_in_file($filestr, 0);
          foreach my $subname (sort keys %$subs_defined_in_file) {
              my $subinfo = $subs_defined_in_file->{$subname};
              next unless $subinfo->is_xsub;

-            $LINE = '';
              my $src = "sub $subname; # xsub\n\t";
-            my $filestr = '';
-
-            foreach my $hash (@{$self->{line}}) {
-
-                my $func = $hash->{func};
-                my $value = $hash->{value};
-                if ($value) {
-                    print OUT $func->(
-                        $subname, undef,
-                        undef, $LINE, $src, $profile,
-                        [ $subinfo ], {}, $filestr
-                    );
-                }
-                else {
-                    print OUT $func->(
-                        $subname, $LINE, $src, $profile, [ $subinfo ], {},  
$filestr
-                    );
-                }
-            }

+            print OUT $line_sub->($subname, $src, undef, undef, [ $subinfo  
], {}, $profile, '');
          }

          print OUT $dataend;
@@ -724,29 +643,6 @@
                     representing the average time per call for a line and
                     returns the output string for that field

-Advanced Parameters:
-
-  Paramter         Description
-  --------------   --------------
-  linestart        Printed at the start of each report line
-  lineend          Printed at the end of each report line
-  column1          |
-  column2          | The four parameters define what to print in each of
-  column3          | the four output fields. See below
-  column4          |
-
- Each of these parameters must be set to a hash reference with any of the
- following key/value pairs:
-
-  Key              Value
-  -------------    -------------
-  start            string printed at the start of the field
-  end              string printed at the end of the field
-  value            identifier for the value that this field will hold
-                     (can be: time, calls, time/calls, source)
-  default          string to be used when there is no value for the field
-                     specified in the 'value' key
-
  Basic Parameters Defaults:

    Parameter         Default
@@ -765,17 +661,6 @@
    callsfunc        undef
    timefunc         undef
    time/callsfunc   undef
-
-Advanced Parameters Defaults:
-
-  Parameter         Default
-  --------------   --------------
-  linestart        {}
-  lineend          { end => "\n" }
-  column1          { value => 'time',      end => ',', default => '0'}
-  column2          { value => 'calls',      end => ',', default => '0'}
-  column3          { value => 'time/call',  end => ',', default => '0'}
-  column4          { value => 'source',    end => '',  default => '' }

  =back


--~--~---------~--~----~------------~-------~--~----~
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