From: Joey Hess <joey@kodama.kitenet.net>
Date: Fri, 21 Mar 2008 10:36:07 +0000 (-0400)
Subject: Precompile pagespecs, about 10% overall speedup
X-Git-Tag: 2.41~47
X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/commitdiff_plain/bf7360347ea3f7a24345004a6c2143d15d3d2e92

Precompile pagespecs, about 10% overall speedup

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

diff --git a/IkiWiki.pm b/IkiWiki.pm
index fc4e044d0..221d1e589 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -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 ! $@;
 } #}}}
 
diff --git a/debian/changelog b/debian/changelog
index c92cf86ed..90b13ed7d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -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