Nicholas Clark's tweaks to Encode compile process
Nick Ing-Simmons [Sun, 10 Feb 2002 10:48:15 +0000 (10:48 +0000)]
 1. Use decimal constants to unit string arrays rather than
    very long string litterals (latter having possible "\0"
    on end issues, and needing ANSI C line splicing).
 2. Replace tail-recursion during insert process with itteration.
Nick C sees 12% speedup from these.

p4raw-id: //depot/perlio@14618

ext/Encode/compile

index ee6d778..8fe6c0f 100755 (executable)
@@ -403,23 +403,22 @@ sub enter
 {
  my ($a,$s,$d,$t,$fb) = @_;
  $t = $a if @_ < 4;
- my $b = substr($s,0,1);
- my $e = $a->{$b};
- unless ($e)
-  {     # 0  1  2  3         4  5
-   $e = [$b,$b,'',{},length($s),0,$fb];
-   $a->{$b} = $e;
-  }
- if (length($s) > 1)
-  {
-   enter($e->[3],substr($s,1),$d,$t,$fb);
-  }
- else
-  {
+
+ while (1) {
+  $s =~ s/(.)//s;
+  my $b = $1;
+  my $e = $a->{$b};
+  #                 0  1  2  3           4  5
+  $a->{$b} = $e = [$b,$b,'',{},1+length($s),0,$fb] unless $e;
+  unless (length($s)) {
    $e->[2] = $d;
    $e->[3] = $t;
    $e->[5] = length($d);
+   return;
   }
+  # Tail recursion.
+  $a = $e->[3];
+ }
 }
 
 
@@ -450,16 +449,12 @@ sub outstring
    }
    $strings{$s} = $sym = $name;
    $strings += length($s);
-   printf $fh "\nstatic const U8 %s[%d] =\n",$name,length($s);
-   # Do in chunks of 16 chars to constrain line length
-   # Assumes ANSI C adjacent string litteral concatenation
-   while (length($s))
-    {
-     my $c = substr($s,0,16,'');
-     print  $fh '"',join('',map(sprintf('\x%02x',ord($_)),split(//,$c))),'"';
-     print  $fh "\n" if length($s);
-    }
-   printf $fh ";\n";
+   my $definition = sprintf "static const U8 %s[%d] = { ",$name,length($s);
+   # Maybe we should assert that these are all <256.
+   $definition .= join(',',unpack "C*",$s);
+   # We have a single long line. Split it at convenient commas.
+   $definition =~ s/(.{74,77},)/$1\n/g;
+   print $fh "$definition };\n\n";
   }
  return $sym;
 }