Re: M4 1.4.10b [beta] released

Bruno Haible <[email protected]>
Newsgroups gmane.comp.gnu.m4.general
Message-ID <[email protected]>
Hi Eric,

> > | Effects on "autoconf" in gettext/gettext-tools:
> > |
> > | m4-1.4.10      50.6 s real + 1.0 sec system
> > | m4-1.4.10b     42.1 s real + 0.9 sec system
> 
> And with --disable-assert, I get:
> 
>                    41.2 s real + 0.9 sec system

With the patch below, I get:

                     36.9 s real + 0.9 sec system

i.e. an additional 10% speedup.

The speed-relevant code is only the case for INPUT_CHAIN. I added the one
for INPUT_STRING because it may be useful it situations I don't know of.


2008-02-28  Bruno Haible  <[email protected]>

	Optimize a code path frequently exercised by autoconf.
	Memory impact: none.
	Speed impact: 10% speedup.
	* src/input.c (next_token): Add an optimized code path for the
	frequent case of rescanning chains or strings.

*** src/input.c.bak	2008-02-23 18:13:02.000000000 +0100
--- src/input.c	2008-02-28 14:52:02.000000000 +0100
***************
*** 1632,1637 ****
--- 1632,1741 ----
        quote_level = 1;
        while (1)
  	{
+ 	  if (curr_quote.len1 == 1 && curr_quote.len2 == 1 && !input_change
+ 	      && isp)
+ 	    {
+ 	      /* The optimized case.  It heavily inlines the MATCH macro and
+ 		 the next_char and next_char_1 functions, to the point that
+ 		 the scan is a loop over a region of memory followed by a
+ 		 simple memory copy operation.
+ 		 The case with INPUT_CHAIN alone can speed up GNU autoconf
+ 		 runs by 10%.  */
+ 	      if (isp->type == INPUT_CHAIN)
+ 		{
+ 		  token_chain *chain = isp->u.u_c.chain;
+ 
+ 		  if (chain)
+ 		    {
+ 		      if (obs != NULL && current_quote_age
+ 			  && chain->quote_age == current_quote_age)
+ 			{
+ 			  /* next_char () would return CHAR_QUOTE here.  */
+ 			  append_quote_token (obs, td);
+ 			}
+ 		      else if (chain->type == CHAIN_STR && chain->u.u_s.len > 0)
+ 			{
+ 			  unsigned char curr_quote_1 =
+ 			    to_uchar (curr_quote.str1[0]);
+ 			  unsigned char curr_quote_2 =
+ 			    to_uchar (curr_quote.str2[0]);
+ 			  const char *p;
+ 			  size_t n;
+ 			  size_t count;
+ 
+ 			  /* Partial consumption invalidates quote age.  */
+ 			  chain->quote_age = 0;
+ 
+ 			  p = chain->u.u_s.str;
+ 			  n = chain->u.u_s.len;
+ 			  do
+ 			    {
+ 			      unsigned char ch = to_uchar (*p);
+ 			      if (ch == curr_quote_2)
+ 				{
+ 				  if (--quote_level == 0)
+ 				    break;
+ 				}
+ 			      else
+ 				quote_level += (ch == curr_quote_1);
+ 			      p++;
+ 			      n--;
+ 			    }
+ 			  while (n > 0);
+ 
+ 			  count = p - chain->u.u_s.str;
+ 			  if (count > 0)
+ 			    obstack_grow (obs_td, chain->u.u_s.str, count);
+ 			  count += (quote_level == 0);
+ 			  chain->u.u_s.str += count;
+ 			  chain->u.u_s.len -= count;
+ 			  if (quote_level == 0)
+ 			    break;
+ 			  continue;
+ 			}
+ 		    }
+ 		}
+ 	      else if (isp->type == INPUT_STRING)
+ 		{
+ 		  if (isp->u.u_s.len > 0)
+ 		    {
+ 		      unsigned char curr_quote_1 =
+ 			to_uchar (curr_quote.str1[0]);
+ 		      unsigned char curr_quote_2 =
+ 			to_uchar (curr_quote.str2[0]);
+ 		      const char *p = isp->u.u_s.str;
+ 		      size_t n = isp->u.u_s.len;
+ 		      size_t count;
+ 
+ 		      do
+ 			{
+ 			  unsigned char ch = to_uchar (*p);
+ 			  if (ch == curr_quote_2)
+ 			    {
+ 			      if (--quote_level == 0)
+ 				break;
+ 			    }
+ 			  else
+ 			    quote_level += (ch == curr_quote_1);
+ 			  p++;
+ 			  n--;
+ 			}
+ 		      while (n > 0);
+ 
+ 		      count = p - isp->u.u_s.str;
+ 		      if (count > 0)
+ 			obstack_grow (obs_td, isp->u.u_s.str, count);
+ 		      count += (quote_level == 0);
+ 		      isp->u.u_s.str += count;
+ 		      isp->u.u_s.len -= count;
+ 		      if (quote_level == 0)
+ 			break;
+ 		      continue;
+ 		    }
+ 		}
+ 	    }
+ 
+ 	  /* The general case.  Proceed character by character.  */
  	  ch = next_char (obs != NULL && current_quote_age);
  	  if (ch == CHAR_EOF)
  	    /* Current_file changed to "" if we see CHAR_EOF, use
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.