Karsten Hopp 9c3490
To: vim-dev@vim.org
Karsten Hopp 9c3490
Subject: Patch 7.1.235
Karsten Hopp 9c3490
Fcc: outbox
Karsten Hopp 9c3490
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 9c3490
Mime-Version: 1.0
Karsten Hopp 9c3490
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp 9c3490
Content-Transfer-Encoding: 8bit
Karsten Hopp 9c3490
------------
Karsten Hopp 9c3490
Karsten Hopp 9c3490
Patch 7.1.235
Karsten Hopp 9c3490
Problem:    Pattern matching is slow when using a lot of simple patterns.
Karsten Hopp 9c3490
Solution:   Avoid allocating memory by not freeing it when it's not so much.
Karsten Hopp 9c3490
	    (Alexei Alexandrov)
Karsten Hopp 9c3490
Files:	    src/regexp.c
Karsten Hopp 9c3490
Karsten Hopp 9c3490
Karsten Hopp 9c3490
*** ../vim-7.1.234/src/regexp.c	Wed Jan  2 15:34:48 2008
Karsten Hopp 9c3490
--- src/regexp.c	Fri Jan 18 20:35:21 2008
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 378,391 ****
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  static char_u		*reg_prev_sub = NULL;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
- #if defined(EXITFREE) || defined(PROTO)
Karsten Hopp 9c3490
-     void
Karsten Hopp 9c3490
- free_regexp_stuff()
Karsten Hopp 9c3490
- {
Karsten Hopp 9c3490
-     vim_free(reg_prev_sub);
Karsten Hopp 9c3490
- }
Karsten Hopp 9c3490
- #endif
Karsten Hopp 9c3490
- 
Karsten Hopp 9c3490
  /*
Karsten Hopp 9c3490
   * REGEXP_INRANGE contains all characters which are always special in a []
Karsten Hopp 9c3490
   * range after '\'.
Karsten Hopp 9c3490
--- 378,383 ----
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 3206,3217 ****
Karsten Hopp 9c3490
  } backpos_T;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  /*
Karsten Hopp 9c3490
!  * regstack and backpos are used by regmatch().  They are kept over calls to
Karsten Hopp 9c3490
!  * avoid invoking malloc() and free() often.
Karsten Hopp 9c3490
   */
Karsten Hopp 9c3490
! static garray_T	regstack;	/* stack with regitem_T items, sometimes
Karsten Hopp 9c3490
! 				   preceded by regstar_T or regbehind_T. */
Karsten Hopp 9c3490
! static garray_T	backpos;	/* table with backpos_T for BACK */
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  /*
Karsten Hopp 9c3490
   * Get pointer to the line "lnum", which is relative to "reg_firstlnum".
Karsten Hopp 9c3490
--- 3198,3236 ----
Karsten Hopp 9c3490
  } backpos_T;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  /*
Karsten Hopp 9c3490
!  * "regstack" and "backpos" are used by regmatch().  They are kept over calls
Karsten Hopp 9c3490
!  * to avoid invoking malloc() and free() often.
Karsten Hopp 9c3490
!  * "regstack" is a stack with regitem_T items, sometimes preceded by regstar_T
Karsten Hopp 9c3490
!  * or regbehind_T.
Karsten Hopp 9c3490
!  * "backpos_T" is a table with backpos_T for BACK
Karsten Hopp 9c3490
!  */
Karsten Hopp 9c3490
! static garray_T	regstack = {0, 0, 0, 0, NULL};
Karsten Hopp 9c3490
! static garray_T	backpos = {0, 0, 0, 0, NULL};
Karsten Hopp 9c3490
! 
Karsten Hopp 9c3490
! /*
Karsten Hopp 9c3490
!  * Both for regstack and backpos tables we use the following strategy of
Karsten Hopp 9c3490
!  * allocation (to reduce malloc/free calls):
Karsten Hopp 9c3490
!  * - Initial size is fairly small.
Karsten Hopp 9c3490
!  * - When needed, the tables are grown bigger (8 times at first, double after
Karsten Hopp 9c3490
!  *   that).
Karsten Hopp 9c3490
!  * - After executing the match we free the memory only if the array has grown.
Karsten Hopp 9c3490
!  *   Thus the memory is kept allocated when it's at the initial size.
Karsten Hopp 9c3490
!  * This makes it fast while not keeping a lot of memory allocated.
Karsten Hopp 9c3490
!  * A three times speed increase was observed when using many simple patterns.
Karsten Hopp 9c3490
   */
Karsten Hopp 9c3490
! #define REGSTACK_INITIAL	2048
Karsten Hopp 9c3490
! #define BACKPOS_INITIAL		64
Karsten Hopp 9c3490
! 
Karsten Hopp 9c3490
! #if defined(EXITFREE) || defined(PROTO)
Karsten Hopp 9c3490
!     void
Karsten Hopp 9c3490
! free_regexp_stuff()
Karsten Hopp 9c3490
! {
Karsten Hopp 9c3490
!     ga_clear(&regstack);
Karsten Hopp 9c3490
!     ga_clear(&backpos);
Karsten Hopp 9c3490
!     vim_free(reg_tofree);
Karsten Hopp 9c3490
!     vim_free(reg_prev_sub);
Karsten Hopp 9c3490
! }
Karsten Hopp 9c3490
! #endif
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  /*
Karsten Hopp 9c3490
   * Get pointer to the line "lnum", which is relative to "reg_firstlnum".
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 3346,3360 ****
Karsten Hopp 9c3490
      char_u	*s;
Karsten Hopp 9c3490
      long	retval = 0L;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
!     reg_tofree = NULL;
Karsten Hopp 9c3490
! 
Karsten Hopp 9c3490
!     /* Init the regstack empty.  Use an item size of 1 byte, since we push
Karsten Hopp 9c3490
!      * different things onto it.  Use a large grow size to avoid reallocating
Karsten Hopp 9c3490
!      * it too often. */
Karsten Hopp 9c3490
!     ga_init2(&regstack, 1, 10000);
Karsten Hopp 9c3490
! 
Karsten Hopp 9c3490
!     /* Init the backpos table empty. */
Karsten Hopp 9c3490
!     ga_init2(&backpos, sizeof(backpos_T), 10);
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
      if (REG_MULTI)
Karsten Hopp 9c3490
      {
Karsten Hopp 9c3490
--- 3365,3389 ----
Karsten Hopp 9c3490
      char_u	*s;
Karsten Hopp 9c3490
      long	retval = 0L;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
!     /* Create "regstack" and "backpos" if they are not allocated yet.
Karsten Hopp 9c3490
!      * We allocate *_INITIAL amount of bytes first and then set the grow size
Karsten Hopp 9c3490
!      * to much bigger value to avoid many malloc calls in case of deep regular
Karsten Hopp 9c3490
!      * expressions.  */
Karsten Hopp 9c3490
!     if (regstack.ga_data == NULL)
Karsten Hopp 9c3490
!     {
Karsten Hopp 9c3490
! 	/* Use an item size of 1 byte, since we push different things
Karsten Hopp 9c3490
! 	 * onto the regstack. */
Karsten Hopp 9c3490
! 	ga_init2(&regstack, 1, REGSTACK_INITIAL);
Karsten Hopp 9c3490
! 	ga_grow(&regstack, REGSTACK_INITIAL);
Karsten Hopp 9c3490
! 	regstack.ga_growsize = REGSTACK_INITIAL * 8;
Karsten Hopp 9c3490
!     }
Karsten Hopp 9c3490
! 
Karsten Hopp 9c3490
!     if (backpos.ga_data == NULL)
Karsten Hopp 9c3490
!     {
Karsten Hopp 9c3490
! 	ga_init2(&backpos, sizeof(backpos_T), BACKPOS_INITIAL);
Karsten Hopp 9c3490
! 	ga_grow(&backpos, BACKPOS_INITIAL);
Karsten Hopp 9c3490
! 	backpos.ga_growsize = BACKPOS_INITIAL * 8;
Karsten Hopp 9c3490
!     }
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
      if (REG_MULTI)
Karsten Hopp 9c3490
      {
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 3525,3533 ****
Karsten Hopp 9c3490
      }
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  theend:
Karsten Hopp 9c3490
!     vim_free(reg_tofree);
Karsten Hopp 9c3490
!     ga_clear(&regstack);
Karsten Hopp 9c3490
!     ga_clear(&backpos);
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
      return retval;
Karsten Hopp 9c3490
  }
Karsten Hopp 9c3490
--- 3554,3570 ----
Karsten Hopp 9c3490
      }
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
  theend:
Karsten Hopp 9c3490
!     /* Free "reg_tofree" when it's a bit big.
Karsten Hopp 9c3490
!      * Free regstack and backpos if they are bigger than their initial size. */
Karsten Hopp 9c3490
!     if (reg_tofreelen > 400)
Karsten Hopp 9c3490
!     {
Karsten Hopp 9c3490
! 	vim_free(reg_tofree);
Karsten Hopp 9c3490
! 	reg_tofree = NULL;
Karsten Hopp 9c3490
!     }
Karsten Hopp 9c3490
!     if (regstack.ga_maxlen > REGSTACK_INITIAL)
Karsten Hopp 9c3490
! 	ga_clear(&regstack);
Karsten Hopp 9c3490
!     if (backpos.ga_maxlen > BACKPOS_INITIAL)
Karsten Hopp 9c3490
! 	ga_clear(&backpos);
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
      return retval;
Karsten Hopp 9c3490
  }
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 3717,3724 ****
Karsten Hopp 9c3490
  #define RA_MATCH	4	/* successful match */
Karsten Hopp 9c3490
  #define RA_NOMATCH	5	/* didn't match */
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
!   /* Init the regstack and backpos table empty.  They are initialized and
Karsten Hopp 9c3490
!    * freed in vim_regexec_both() to reduce malloc()/free() calls. */
Karsten Hopp 9c3490
    regstack.ga_len = 0;
Karsten Hopp 9c3490
    backpos.ga_len = 0;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
--- 3754,3761 ----
Karsten Hopp 9c3490
  #define RA_MATCH	4	/* successful match */
Karsten Hopp 9c3490
  #define RA_NOMATCH	5	/* didn't match */
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
!   /* Make "regstack" and "backpos" empty.  They are allocated and freed in
Karsten Hopp 9c3490
!    * vim_regexec_both() to reduce malloc()/free() calls. */
Karsten Hopp 9c3490
    regstack.ga_len = 0;
Karsten Hopp 9c3490
    backpos.ga_len = 0;
Karsten Hopp 9c3490
  
Karsten Hopp 9c3490
*** ../vim-7.1.234/src/version.c	Fri Jan 18 17:39:10 2008
Karsten Hopp 9c3490
--- src/version.c	Fri Jan 18 20:33:26 2008
Karsten Hopp 9c3490
***************
Karsten Hopp 9c3490
*** 668,669 ****
Karsten Hopp 9c3490
--- 668,671 ----
Karsten Hopp 9c3490
  {   /* Add new patch number below this line */
Karsten Hopp 9c3490
+ /**/
Karsten Hopp 9c3490
+     235,
Karsten Hopp 9c3490
  /**/
Karsten Hopp 9c3490
Karsten Hopp 9c3490
-- 
Karsten Hopp 9c3490
NEIL INNES PLAYED: THE FIRST SELF-DESTRUCTIVE MONK, ROBIN'S LEAST FAVORITE
Karsten Hopp 9c3490
                   MINSTREL, THE PAGE CRUSHED BY A RABBIT, THE OWNER OF A DUCK
Karsten Hopp 9c3490
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp 9c3490
Karsten Hopp 9c3490
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 9c3490
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 9c3490
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp 9c3490
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///