Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[src/core/Cool-str.pm] 500% speedup of .trans

Keep a hash with the next index of each substring to be substituted,
and then pick the smallest one through each iteration. (Or, more
informally, "skip the boring parts".) This makes the number of
iterations through the main loop proportional to the number of
substitutions actually made.
  • Loading branch information...
commit 2c66f9a19607046e4d6ceffbbfb7b47710286c2f 1 parent 690e370
Carl Mäsak authored November 07, 2010

Showing 1 changed file with 10 additions and 34 deletions. Show diff stats Hide diff stats

  1. 44  src/core/Cool-str.pm
44  src/core/Cool-str.pm
@@ -176,12 +176,10 @@ augment class Cool {
176 176
         }
177 177
 
178 178
         my %c;
179  
-        my %prefixes;
180 179
         for (@changes) -> $p {
181 180
             die "$p.perl is not a Pair" unless $p ~~ Pair;
182 181
             my @from = expand $p.key;
183 182
             my @to   = expand $p.value;
184  
-#            warn "Substitution is longer than pattern\n" if @to > @from;
185 183
             if @to {
186 184
                 @to = @to xx ceiling(@from / @to);
187 185
             } else {
@@ -189,46 +187,24 @@ augment class Cool {
189 187
             }
190 188
             for @from Z @to -> $f, $t {
191 189
                 if %c.exists($f) && %c{$f} ne $t {
192  
-#                    warn "Ambiguous transliteration rule for '$f'; "
193  
-#                         ~ "using the first one (transliteration to '$t')";
194 190
                 } else {
195  
-                    if $f.chars > 1 {
196  
-                        %prefixes{$f.substr(0, 1)} //= [];
197  
-                        %prefixes{$f.substr(0, 1)}.push($f);
198  
-                    }
199 191
                     %c{$f} = $t;
200 192
                 }
201 193
             }
202 194
         }
203 195
 
204  
-        # should be replaced by a proper trie implementation
205  
-        # at some point
206  
-        for %prefixes.keys {
207  
-            %prefixes{$_}.=sort({-.chars});
  196
+        my $i = 0;
  197
+        my $r = "";
  198
+        my %h = %c.keys Z=> map { self.index($_) // Inf }, %c.keys;
  199
+        while ($_ = %h.pairs.sort({-.chars}).min: *.value).value < Inf {
  200
+            %h{.key} = self.index(.key, .value + 1) // Inf;
  201
+            next if .value < $i;
  202
+            $r ~= self.substr($i, .value - $i) ~ %c{.key};
  203
+            $i = .value + .key.chars;
208 204
         }
  205
+        $r ~= self.substr($i);
209 206
 
210  
-        my @res;
211  
-        my $l = $.chars;
212  
-        loop (my $i = 0; $i < $l; ++$i) {
213  
-            my $c = $.substr($i, 1);
214  
-            my $success = 0;
215  
-            if %prefixes.exists($c) {
216  
-                for %prefixes{$c}.list {
217  
-                    if self.substr($i, .chars) eq $_ {
218  
-                        @res.push: %c{$_};
219  
-                        $success = 1;
220  
-                        $i += .chars - 1;
221  
-                        last;
222  
-                    }
223  
-                }
224  
-            }
225  
-            unless $success {
226  
-                @res.push: %c.exists($c)
227  
-                            ?? %c{$c}
228  
-                            !! $c;
229  
-            }
230  
-        }
231  
-        @res.join: '';
  207
+        return $r;
232 208
     }
233 209
 
234 210
 

0 notes on commit 2c66f9a

Please sign in to comment.
Something went wrong with that request. Please try again.