While trying to figure out whether m4_curry will be a win or not, I noticed this low-hanging fruit. It dropped the speed of 'autoconf -f' on coreutils from 16.441s to 15.786s (or about 4% improvement).
$ autoconf --trace _m4_text_wrap:'$n' | wc -l 882 $ autoconf --trace m4_qlen:'$n' | wc -l 12708 $ autoconf --trace m4_qlen:'$1' | sort | uniq -c | sort -k1,1n | tail -n10 499 have 589 you 604 1 756 the 836 to 849 Define 855 if 862 862 /* 890 */ $ _m4_text_wrap is by far the biggest client of m4_foreach_w (I'm trying to rewrite it to use m4_map_args/m4_curry or determine if yet another interface would be faster). That in turn calls m4_qlen on every word, which was doing an m4_if, m4_index, and m4_len on every word without a quadrigraph, and additional work where quadrigraphs were concerned. Since we are repeatedly checking the length of the same frequent short strings, caching is a win, reducing the common path to m4_ifdef and _m4_defn. The patch is intentionally written to expand $1 as seldom as possible in m4_qlen proper, so that m4 has less text to scan in the common case (but it sure makes for a hairy definition!). >From 257a2a68d02470c252b1183308d9f484a56c8ae6 Mon Sep 17 00:00:00 2001 From: Eric Blake <[EMAIL PROTECTED]> Date: Thu, 16 Oct 2008 10:14:09 -0600 Subject: [PATCH] Speed up m4_qlen with caching. * lib/m4sugar/m4sugar.m4 (_m4_qlen): Renamed from old m4_qlen. (m4_qlen): Cache results for speed. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> --- ChangeLog | 6 ++++++ lib/m4sugar/m4sugar.m4 | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8eef61d..dfbbdfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-10-16 Eric Blake <[EMAIL PROTECTED]> + + Speed up m4_qlen with caching. + * lib/m4sugar/m4sugar.m4 (_m4_qlen): Renamed from old m4_qlen. + (m4_qlen): Cache results for speed. + 2008-10-16 Paolo Bonzini <[EMAIL PROTECTED]> Add a testcase using more then one language. diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 2e02a77..681f4b0 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -2221,7 +2221,7 @@ dnl either way, insert the word m4_eval(m4_Indent + m4_qlen(_m4_defn([m4_Word])) + 1)) [$2]], [m4_Separator[]])_m4_defn([m4_Word])])]], -dnl finally, clean up the local variabls +dnl finally, clean up the local variables [[_m4_popdef([m4_Separator], [m4_Cursor], [m4_Indent])]])) @@ -2246,12 +2246,19 @@ m4_define([m4_text_box], # --------------- # Expands to the length of STRING after autom4te converts all quadrigraphs. # -# Avoid bpatsubsts for the common case of no quadrigraphs. +# Avoid bpatsubsts for the common case of no quadrigraphs. Cache +# results, as configure scripts tend to ask about lengths of common +# strings like `/*' and `*/' rather frequently. Minimize the number +# of times that $1 occurs in m4_qlen, so there is less text to parse +# on a cache hit. m4_define([m4_qlen], -[m4_if(m4_index([$1], [EMAIL PROTECTED]), [-1], [m4_len([$1])], - [m4_len(m4_bpatsubst([[$1]], - [EMAIL PROTECTED](\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&[EMAIL PROTECTED])], - [\3]))])]) +[m4_ifdef([$0-$1], [_m4_defn([$0-]], [_$0(])[$1])]) +m4_define([_m4_qlen], +[m4_define([m4_qlen-$1], +m4_if(m4_index([$1], [EMAIL PROTECTED]), [-1], [m4_len([$1])], + [m4_len(m4_bpatsubst([[$1]], + [EMAIL PROTECTED](\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&[EMAIL PROTECTED])], + [\3]))]))_m4_defn([m4_qlen-$1])]) # m4_qdelta(STRING) -- 1.6.0.2