[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: speed up make_paragraphs
From: |
Alexandre Duret-Lutz |
Subject: |
FYI: speed up make_paragraphs |
Date: |
Fri, 06 Aug 2004 00:30:24 +0200 |
User-agent: |
Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux) |
The number for substitution done by make_paragraph was linear in
the number of items in %transform (4 substitutions par items + 2
extra substitutions), even though many items were not used.
This patch replaces all these substitutions by a single
substitution (+ 2 extra substitutions too) that calls back
&transform on each token it encounters.
Running automake on Coreutils went down from 8.5sec to 7.5sec.
That's not spectacular, but its measurable. I expect the speed
up to be more important when more sources are involved.
I wonder if caching preprocessed versions of the template files
(after the first substitution) wouldn't help too.
2004-08-05 Alexandre Duret-Lutz <address@hidden>
Speed up make_paragraphs.
* automake.in (handle_languages): Always define SUBDIROBJ,
DERIVED-EXT, and DIST_SOURCE, because the new transform() will
abort on unknown tokens.
(transform): Rewrite with different semantics.
(make_paragraphs): Make a single pass over the paragraph to
transform all template tokens instead of doing as much passes as
possible token.
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1574
diff -u -r1.1574 automake.in
--- automake.in 5 Aug 2004 21:13:54 -0000 1.1574
+++ automake.in 5 Aug 2004 22:01:54 -0000
@@ -1143,7 +1143,13 @@
'FASTDEP' => $FASTDEP,
'-c' => $lang->compile_flag || '',
'MORE-THAN-ONE'
- => (count_files_for_language ($lang->name) >
1));
+ => (count_files_for_language ($lang->name) >
1),
+ # These are not used, but they need to be defined
+ # so &transform do not complain.
+ SUBDIROBJ => 0,
+ 'DERIVED-EXT' => 'BUG',
+ DIST_SOURCE => 1,
+ );
# Generate the appropriate rules for this extension.
if (((! option 'no-dependencies') && $lang->autodep ne 'no')
@@ -6101,6 +6107,38 @@
return $_;
}
+# transform($TOKEN, \%PAIRS)
+# ==========================
+# If ($TOKEN, $VAL) is in %PAIRS:
+# - replaces %$TOKEN% with $VAL,
+# - enables/disables ?$TOKEN? and ?!$TOKEN?,
+# - replaces %?$TOKEN% with TRUE or FALSE.
+sub transform($$)
+{
+ my ($token, $transform) = @_;
+
+ if (substr ($token, 0, 1) eq '%')
+ {
+ my $cond = (substr ($token, 1, 1) eq '?') ? 1 : 0;
+ $token = substr ($token, 1 + $cond, -1);
+ my $val = $transform->{$token};
+ prog_error "Unknown %token% `$token'" unless defined $val;
+ if ($cond)
+ {
+ return $val ? 'TRUE' : 'FALSE';
+ }
+ else
+ {
+ return $val;
+ }
+ }
+ # Now $token is '?xxx?' or '?!xxx?'.
+ my $neg = (substr ($token, 1, 1) eq '!') ? 1 : 0;
+ $token = substr ($token, 1 + $neg, -1);
+ my $val = $transform->{$token};
+ prog_error "Unknown ?token? `$token' (neg = $neg)" unless defined $val;
+ return (!!$val == $neg) ? '##%' : '';
+}
# @PARAGRAPHS
# &make_paragraphs ($MAKEFILE, [%TRANSFORM])
@@ -6111,11 +6149,9 @@
{
my ($file, %transform) = @_;
- # Complete %transform with global options and make it a Perl $command.
+ # Complete %transform with global options.
# Note that %transform goes last, so it overrides global options.
- my $command =
- "s/$IGNORE_PATTERN//gm;"
- . transform ('CYGNUS' => !! option 'cygnus',
+ %transform = ('CYGNUS' => !! option 'cygnus',
'MAINTAINER-MODE'
=> $seen_maint_mode ? subst ('MAINTAINER_MODE_TRUE') : '',
@@ -6140,9 +6176,7 @@
'LIBTOOL' => !! var ('LIBTOOL'),
'NONLIBTOOL' => 1,
'FIRST' => ! $transformed_files{$file},
- %transform)
- # We don't need more than two consecutive new-lines.
- . 's/\n{3,}/\n\n/g';
+ %transform);
$transformed_files{$file} = 1;
@@ -6154,17 +6188,25 @@
undef $/;
$_ = $fc_file->getline;
$/ = $saved_dollar_slash;
- eval $command;
$fc_file->close;
- my $content = $_;
+
+ # Remove ##-comments.
+ # Besides we don't need more than two consecutive new-lines.
+ s/(?:$IGNORE_PATTERN|(?<=\n\n)\n+)//gom;
+ # Substitute Automake template tokens.
+ s/(?:%\??[\w\-]+%|\?!?[\w\-]+\?)/transform($&, \%transform)/ge;
+ # transform() may have added some ##%-comments to strip.
+ # (we use `##%' instead of `##' so we can distinguish ##%##%##% from
+ # ####### and do not remove the latter.)
+ s/^[ \t]*(?:##%)+.*\n//gm;
# Split at unescaped new lines.
- my @lines = split (/(?<!\\)\n/, $content);
+ my @lines = split (/(?<!\\)\n/, $_);
my @res;
while (defined ($_ = shift @lines))
{
- my $paragraph = "$_";
+ my $paragraph = $_;
# If we are a rule, eat as long as we start with a tab.
if (/$RULE_PATTERN/smo)
{
@@ -6187,7 +6229,6 @@
}
push @res, $paragraph;
- $paragraph = '';
}
return @res;
@@ -6410,38 +6451,6 @@
}
-# $REGEXP
-# &transform (%PAIRS)
-# -------------------
-# For each ($TOKEN, $VAL) in %PAIRS produce a replacement expression
-# suitable for file_contents which:
-# - replaces %$TOKEN% with $VAL,
-# - enables/disables ?$TOKEN? and ?!$TOKEN?,
-# - replaces %?$TOKEN% with TRUE or FALSE.
-sub transform (%)
-{
- my (%pairs) = @_;
- my $result = '';
-
- while (my ($token, $val) = each %pairs)
- {
- $result .= "s/\Q%$token%\E/\Q$val\E/gm;";
- if ($val)
- {
- $result .= "s/\Q?$token?\E//gm;s/^.*\Q?!$token?\E.*\\n//gm;";
- $result .= "s/\Q%?$token%\E/TRUE/gm;";
- }
- else
- {
- $result .= "s/\Q?!$token?\E//gm;s/^.*\Q?$token?\E.*\\n//gm;";
- $result .= "s/\Q%?$token%\E/FALSE/gm;";
- }
- }
-
- return $result;
-}
-
-
# &append_exeext ($MACRO)
# -----------------------
# Macro is an Automake magic macro which primary is PROGRAMS, e.g.
--
Alexandre Duret-Lutz
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: speed up make_paragraphs,
Alexandre Duret-Lutz <=