[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: documentation ideas from autoconf
From: |
Eric Blake |
Subject: |
Re: documentation ideas from autoconf |
Date: |
Thu, 12 Feb 2009 22:04:00 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Eric Blake <ebb9 <at> byu.net> writes:
> Fortunately, autoconf had already resolved the issue, as a side effect of
> writing a more efficient copy algorithm. So I'm applying this followup to
> branch-1.6 and master, then backporting the series of doc patches to branch-
1.4:
> +++ b/examples/stack_sep.m4
> @@ -0,0 +1,17 @@
> +divert(`-1')
> +# stack_foreach_sep(macro, pre, post, sep)
> +# Invoke PRE`'defn`'POST with a single argument of each definition
> +# from the definition stack of MACRO, starting with the oldest, and
> +# separated by SEP between definitions.
> +define(`stack_foreach_sep',
> +`_stack_reverse_sep(`$1', `tmp-$1')'dnl
> +`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
> +# stack_foreach_sep_lifo(macro, pre, post, sep)
> +# Like stack_foreach_sep, but starting with the newest definition.
> +define(`stack_foreach_sep_lifo',
> +`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
> +`_stack_reverse_sep(`tmp-$1', `$1')')
> +define(`_stack_reverse_sep',
> +`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
> + `$1', `$2', `$4`'$3')')')
> +divert`'dnl
Oops. That implementation is quadratic, as I just discovered on the autoconf
list today. I'm installing this on all three branches, to provide a linear
alternative.
From: Eric Blake <address@hidden>
Date: Thu, 12 Feb 2009 14:59:08 -0700
Subject: [PATCH] Avoid quadratic code when walking definition stack.
* examples/stack_sep.m4: Use linear, not quadratic
implementation.
* doc/m4.texinfo (Improved copy): Fix documentation and add test,
based on recent autoconf bug fix.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 8 ++++++++
doc/m4.texinfo | 45 +++++++++++++++++++++++++++++++++++----------
examples/stack_sep.m4 | 6 +++---
3 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c55e79f..3495018 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-12 Eric Blake <address@hidden>
+
+ Avoid quadratic code when walking definition stack.
+ * examples/stack_sep.m4: Use linear, not quadratic
+ implementation.
+ * doc/m4.texinfo (Improved copy): Fix documentation and add test,
+ based on recent autoconf bug fix.
+
2009-01-24 Eric Blake <address@hidden>
Add URLs to --help output.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index c09d771..9bbfcfd 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -8199,13 +8199,21 @@ Improved copy
construct macro calls with more than one argument, without passing
builtin tokens through a macro call. It is likewise possible to
directly reference the stack definitions without a macro call, by
-leaving @var{pre} and @var{post} empty. The new macro also adds a
-separator that is only output after the first iteration of the helper
address@hidden, implemented by prepending the original
address@hidden to @var{pre} and omitting a @var{sep} argument in subsequent
-iterations. As an added bonus, using @code{stack_foreach_sep} to
-implement @code{copy} performs fewer macro invocations. The improved
-stack walking macros are available in
+leaving @var{pre} and @var{post} empty. Thus, in addition to fixing
address@hidden on builtin tokens, it also executes with fewer macro
+invocations.
+
+The new macro also adds a separator that is only output after the first
+iteration of the helper @code{_stack_reverse_sep}, implemented by
+prepending the original @var{sep} to @var{pre} and omitting a @var{sep}
+argument in subsequent iterations. Note that the empty string that
+separates @var{sep} from @var{pre} is provided as part of the fourth
+argument when originally calling @code{_stack_reverse_sep}, and not by
+writing @code{$4`'$3} as the third argument in the recursive call; while
+the other approach would give the same output, it does so at the expense
+of increasing the argument size on each iteration of
address@hidden, which results in quadratic instead of linear
+execution time. The improved stack walking macros are available in
@address@hidden/@/examples/@/stack_sep.m4}:
@comment examples
@@ -8238,18 +8246,35 @@ Improved copy
@result{}# separated by SEP between definitions.
@result{}define(`stack_foreach_sep',
@result{}`_stack_reverse_sep(`$1', `tmp-$1')'dnl
address@hidden(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
address@hidden(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
@result{}# stack_foreach_sep_lifo(macro, pre, post, sep)
@result{}# Like stack_foreach_sep, but starting with the newest definition.
@result{}define(`stack_foreach_sep_lifo',
address@hidden(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
address@hidden(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
@result{}`_stack_reverse_sep(`tmp-$1', `$1')')
@result{}define(`_stack_reverse_sep',
@result{}`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
address@hidden `$1', `$2', `$4`'$3')')')
address@hidden `$1', `$2', `$4$3')')')
@result{}divert`'dnl
@end example
address@hidden
address@hidden Not worth putting in the manual, but make sure that
address@hidden stack_foreach_sep has linear performance.
+
address@hidden examples
address@hidden
+$ @kbd {m4 -I examples}
+include(`forloop3.m4')include(`stack_sep.m4')dnl
+forloop(`i', `1', `10000', `pushdef(`s', i)')
address@hidden
+define(`colon', `:')define(`dash', `-')
address@hidden
+len(stack_foreach_sep(`s', `dash', `', `colon'))
address@hidden
address@hidden example
address@hidden ignore
+
@node Improved m4wrap
@section Solution for @code{m4wrap}
diff --git a/examples/stack_sep.m4 b/examples/stack_sep.m4
index b11bc83..767d15e 100644
--- a/examples/stack_sep.m4
+++ b/examples/stack_sep.m4
@@ -5,13 +5,13 @@ divert(`-1')
# separated by SEP between definitions.
define(`stack_foreach_sep',
`_stack_reverse_sep(`$1', `tmp-$1')'dnl
-`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
+`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
# stack_foreach_sep_lifo(macro, pre, post, sep)
# Like stack_foreach_sep, but starting with the newest definition.
define(`stack_foreach_sep_lifo',
-`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
+`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
`_stack_reverse_sep(`tmp-$1', `$1')')
define(`_stack_reverse_sep',
`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
- `$1', `$2', `$4`'$3')')')
+ `$1', `$2', `$4$3')')')
divert`'dnl
--
1.6.1.2
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: documentation ideas from autoconf,
Eric Blake <=