[svn:parrot] r42177 - trunk/tools/dev

japhb at svn.parrot.org japhb at svn.parrot.org
Sat Oct 31 04:09:33 UTC 2009


Author: japhb
Date: Sat Oct 31 04:09:15 2009
New Revision: 42177
URL: https://trac.parrot.org/parrot/changeset/42177

Log:
[tools] pprof2cg.pl: Stats bug fix + first tuning (42.5% less time on one benchmark)

Modified:
   trunk/tools/dev/pprof2cg.pl

Modified: trunk/tools/dev/pprof2cg.pl
==============================================================================
--- trunk/tools/dev/pprof2cg.pl	Sat Oct 31 02:59:22 2009	(r42176)
+++ trunk/tools/dev/pprof2cg.pl	Sat Oct 31 04:09:15 2009	(r42177)
@@ -6,7 +6,7 @@
 use strict;
 use warnings;
 
-use Data::Dumper;
+# use Data::Dumper;
 
 =head1 Name
 
@@ -124,6 +124,8 @@
     my $ctx_stack = [];
     my $filename  = $argv->[0];
 
+    $stats->{global_stats}{total_time} = 0;
+
     open(my $in_fh, '<', $filename) or die "couldn't open $filename for reading: $!";
 
     while (my $line = <$in_fh>) {
@@ -175,18 +177,22 @@
         #context switch
         elsif (/^CS:(.*)$/) {
 
-            my $cs_hash      = split_vars($1);
+            # Decode string in the format C<{x{key1:value1}x}{x{key2:value2}x}>
+            my %cs_hash      = $1 =~ /{x{([^:]+):(.*?)}x}/g
+                or die "invalidly formed line '$line'";
+            my $cs_hash      = \%cs_hash;
+
             my $is_first     = scalar(@$ctx_stack) == 0;
-            my $is_redundant = !$is_first && ($ctx_stack->[0]{'ctx'} eq $cs_hash->{'ctx'});
-            my $reused_ctx   = $is_redundant && ($ctx_stack->[0]{'sub'} ne $cs_hash->{'sub'});
-            my $is_call      = scalar(grep {$_->{'ctx'} eq $cs_hash->{'ctx'}} @$ctx_stack) == 0;
+            my $is_redundant = !$is_first && ($ctx_stack->[0]{'ctx'} eq $cs_hash{ctx});
+            my $reused_ctx   = $is_redundant && ($ctx_stack->[0]{'sub'} ne $cs_hash{sub});
+            my $is_call      = scalar(grep {$_->{'ctx'} eq $cs_hash{ctx}} @$ctx_stack) == 0;
 
             if ($is_first) {
                 $ctx_stack->[0] = $cs_hash;
             }
             elsif ($reused_ctx) {
-                $ctx_stack->[0]{'sub'} = $cs_hash->{'sub'};
-                $ctx_stack->[0]{'ns'}  = $cs_hash->{'ns'};
+                $ctx_stack->[0]{'sub'} = $cs_hash{sub};
+                $ctx_stack->[0]{'ns'}  = $cs_hash{ns};
             }
             elsif ($is_redundant) {
                 #don't do anything
@@ -195,14 +201,14 @@
                 $ctx_stack->[0]{'op_num'}++;
                 my $extra = {
                     op_name => "CALL",
-                    target  => $cs_hash->{'ns'}
+                    target  => $cs_hash{ns}
                 };
                 store_stats($stats, $ctx_stack->[0], 0, $extra );
                 unshift @$ctx_stack, $cs_hash;
             }
             else {
                 #shift contexts off the stack until one matches the current ctx
-                while ($ctx_stack->[0]->{'ctx'} ne $cs_hash->{'ctx'}) {
+                while ($ctx_stack->[0]->{'ctx'} ne $cs_hash{ctx}) {
                     my $ctx = shift @$ctx_stack;
                 }
             }
@@ -213,7 +219,10 @@
             @$ctx_stack = ();
         }
         elsif (/^OP:(.*)$/) {
-            my $op_hash = split_vars($1);
+            # Decode string in the format C<{x{key1:value1}x}{x{key2:value2}x}>
+            my %op_hash = $1 =~ /{x{([^:]+):(.*?)}x}/g
+                or die "invalidly formed line '$line'";
+            my $op_hash = \%op_hash;
 
             die "input file did not specify an initial context" if (@$ctx_stack == 0);
 
@@ -226,12 +235,14 @@
 
             $ctx_stack->[0]{'line'} = $op_hash->{'line'};
             my $extra = { op_name => $op_hash->{'op'} };
-            store_stats($stats, $ctx_stack->[0], $op_hash->{'time'}, $extra);
+            my $time  = $op_hash->{time};
+
+            $stats->{global_stats}{total_time} += $time;
+            store_stats($stats, $ctx_stack->[0], $time, $extra);
 
             $extra->{'no_hits'} = 1;
-            for my $frame (@$ctx_stack[1 .. scalar(@$ctx_stack)-1 ]) {
-                store_stats($stats, $frame, $op_hash->{'time'}, $extra);
-            }
+            store_stats($stats, $ctx_stack->[$_], $time, $extra)
+                for 1 .. $#$ctx_stack;
         }
         else {
             die "Unrecognized line format: \"$line\"";
@@ -269,25 +280,6 @@
     }
 }
 
-=item C<split_vars>
-
-This function takes a string specifying 1 or more key/value mappings and
-returns a reference to a hash containing those keys and values.  The string
-must be in the format C<{x{key1:value1}x}{x{key2:value2}x}>.
-
-=cut
-
-sub split_vars {
-    my $href;
-    my $str = shift;
-    die "invalidly formed line '$str'"
-        unless $str =~ /({x{  [^:]+  : (.*?) }x})+/x;
-    while ($str =~ /\G   {x{ ([^:]+) : (.*?) }x} /cxg) {
-        $href->{$1} = $2;
-    }
-    return $href;
-}
-
 =item C<store_stats>
 
 This function adds statistical data to the C<$stats> hash reference.  The
@@ -300,34 +292,19 @@
 =cut
 
 sub store_stats {
-    my $stats   = shift;
-    my $locator = shift;
-    my $time    = shift;
-    my $extra   = shift;
-
-    my $file   = $locator->{'file'};
-    my $ns     = $locator->{'ns'};
-    my $line   = $locator->{'line'};
-    my $op_num = $locator->{'op_num'};
+    my ($stats, $loc, $time, $extra) = @_;
 
-    if (exists $stats->{'global_stats'}{'total_time'}) {
-        $stats->{'global_stats'}{'total_time'} += $time;
-    }
-    else {
-        $stats->{'global_stats'}{'total_time'} = $time;
-    }
+    my $by_op = ($stats->{$loc->{file}}{$loc->{ns}}{$loc->{line}}[$loc->{op_num}] ||= {});
 
-    if (exists $stats->{$file}{$ns}{$line}[$op_num]) {
-        $stats->{$file}{$ns}{$line}[$op_num]{'hits'}++
-            unless exists $extra->{no_hits};
-        $stats->{$file}{$ns}{$line}[$op_num]{'time'} += $time;
+    if ($by_op->{hits}) {
+        $by_op->{hits} ++ unless exists $extra->{no_hits};
+        $by_op->{time} += $time;
     }
     else {
-        $stats->{$file}{$ns}{$line}[$op_num]{'hits'} = 1;
-        $stats->{$file}{$ns}{$line}[$op_num]{'time'} = $time;
-        for my $key (keys %{$extra}) {
-            $stats->{$file}{$ns}{$line}[$op_num]{$key} = $extra->{$key};
-        }
+        $by_op->{hits} = 1;
+        $by_op->{time} = $time;
+
+        $by_op->{$_} = $extra->{$_} for keys %$extra;
     }
 }
 


More information about the parrot-commits mailing list