Precompile pagespecs, about 10% overall speedup
authorJoey Hess <joey@kodama.kitenet.net>
Fri, 21 Mar 2008 10:36:07 +0000 (06:36 -0400)
committerJoey Hess <joey@kodama.kitenet.net>
Fri, 21 Mar 2008 10:36:07 +0000 (06:36 -0400)
About 12% of ikiwiki runtime was spent in pagespec_match. It was evaling
the same pagespec code over and over again. This changes pagespec_translate
to return memoized, precompiled functions that can be called to match against
a given pagespec.

This also allows getting rid of the weird variable scoping trick that had
to be in effect for pagespec_translate to be called -- the variables are
now just fed into the function it returns.

On my laptop, this drops build time for the docwiki from about 60 to 50
seconds.

IkiWiki.pm
debian/changelog

index fc4e044d0c944cea010e7a02126eba45816f6422..221d1e589d1a977ec97648220e78804565e07be3 100644 (file)
@@ -1169,8 +1169,6 @@ sub pagespec_merge ($$) { #{{{
 } #}}}
 
 sub pagespec_translate ($) { #{{{
-       # This assumes that $page and @params are in scope in the function
-       # that evalulates the translated pagespec code.
        my $spec=shift;
 
        # Support for old-style GlobLists.
@@ -1207,18 +1205,18 @@ sub pagespec_translate ($) { #{{{
                }
                elsif ($word =~ /^(\w+)\((.*)\)$/) {
                        if (exists $IkiWiki::PageSpec::{"match_$1"}) {
-                               $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@params)";
+                               $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@_)";
                        }
                        else {
                                $code.=' 0';
                        }
                }
                else {
-                       $code.=" IkiWiki::PageSpec::match_glob(\$page, ".safequote($word).", \@params)";
+                       $code.=" IkiWiki::PageSpec::match_glob(\$page, ".safequote($word).", \@_)";
                }
        }
 
-       return $code;
+       return eval 'sub { my $page=shift; '.$code.' }';
 } #}}}
 
 sub pagespec_match ($$;@) { #{{{
@@ -1231,19 +1229,15 @@ sub pagespec_match ($$;@) { #{{{
                unshift @params, 'location';
        }
 
-       my $ret=eval pagespec_translate($spec);
+       my $sub=pagespec_translate($spec);
        return IkiWiki::FailReason->new('syntax error') if $@;
-       return $ret;
+       return $sub->($page, @params);
 } #}}}
 
 sub pagespec_valid ($) { #{{{
        my $spec=shift;
 
-       # used by generated code
-       my $page="";
-       my @params;
-
-       eval pagespec_translate($spec);
+       my $sub=pagespec_translate($spec);
        return ! $@;
 } #}}}
 
index c92cf86ed8edbac91cbc716f1fdec4a7bde3b340..90b13ed7df191ba0c81d1cf63004c011ca673329 100644 (file)
@@ -57,6 +57,7 @@ ikiwiki (2.41) UNRELEASED; urgency=low
   * Close meta tag for redir properly.
   * smiley: Detect smileys inside pre and code tags, and do not expand.
   * inline: Crazy optimisation to work around slow markdown.
+  * Precompile pagespecs, about 10% overall speedup.
 
  -- martin f. krafft <madduck@debian.org>  Sun, 02 Mar 2008 17:46:38 +0100