home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.3 / 7.3.1133 < prev    next >
Encoding:
Internet Message Format  |  2013-06-05  |  8.6 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.1133
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.3.1133
  11. Problem:    New regexp engine is a bit slow.
  12. Solution:   Skip ahead to a character that must match.  Don't try matching a
  13.         "^" patter past the start of line.
  14. Files:        src/regexp_nfa.c, src/regexp.h
  15.  
  16.  
  17. *** ../vim-7.3.1132/src/regexp_nfa.c    2013-06-06 18:04:47.000000000 +0200
  18. --- src/regexp_nfa.c    2013-06-06 18:37:23.000000000 +0200
  19. ***************
  20. *** 257,262 ****
  21. --- 257,264 ----
  22.   static int nfa_ll_index = 0;
  23.   
  24.   static int nfa_regcomp_start __ARGS((char_u *expr, int re_flags));
  25. + static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
  26. + static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
  27.   static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end, int extra_newl));
  28.   static int nfa_emit_equi_class __ARGS((int c, int neg));
  29.   static int nfa_regatom __ARGS((void));
  30. ***************
  31. *** 331,336 ****
  32. --- 333,487 ----
  33.   }
  34.   
  35.   /*
  36. +  * Figure out if the NFA state list starts with an anchor, must match at start
  37. +  * of the line.
  38. +  */
  39. +     static int
  40. + nfa_get_reganch(start, depth)
  41. +     nfa_state_T *start;
  42. +     int        depth;
  43. + {
  44. +     nfa_state_T *p = start;
  45. +     if (depth > 4)
  46. +     return 0;
  47. +     while (p != NULL)
  48. +     {
  49. +     switch (p->c)
  50. +     {
  51. +         case NFA_BOL:
  52. +         case NFA_BOF:
  53. +         return 1; /* yes! */
  54. +         case NFA_ZSTART:
  55. +         case NFA_ZEND:
  56. +         case NFA_CURSOR:
  57. +         case NFA_VISUAL:
  58. +         case NFA_MOPEN:
  59. +         case NFA_MOPEN1:
  60. +         case NFA_MOPEN2:
  61. +         case NFA_MOPEN3:
  62. +         case NFA_MOPEN4:
  63. +         case NFA_MOPEN5:
  64. +         case NFA_MOPEN6:
  65. +         case NFA_MOPEN7:
  66. +         case NFA_MOPEN8:
  67. +         case NFA_MOPEN9:
  68. +         case NFA_NOPEN:
  69. + #ifdef FEAT_SYN_HL
  70. +         case NFA_ZOPEN:
  71. +         case NFA_ZOPEN1:
  72. +         case NFA_ZOPEN2:
  73. +         case NFA_ZOPEN3:
  74. +         case NFA_ZOPEN4:
  75. +         case NFA_ZOPEN5:
  76. +         case NFA_ZOPEN6:
  77. +         case NFA_ZOPEN7:
  78. +         case NFA_ZOPEN8:
  79. +         case NFA_ZOPEN9:
  80. + #endif
  81. +         p = p->out;
  82. +         break;
  83. +         case NFA_SPLIT:
  84. +         return nfa_get_reganch(p->out, depth + 1)
  85. +                        && nfa_get_reganch(p->out1, depth + 1);
  86. +         default:
  87. +         return 0; /* noooo */
  88. +     }
  89. +     }
  90. +     return 0;
  91. + }
  92. + /*
  93. +  * Figure out if the NFA state list starts with a character which must match
  94. +  * at start of the match.
  95. +  */
  96. +     static int
  97. + nfa_get_regstart(start, depth)
  98. +     nfa_state_T *start;
  99. +     int        depth;
  100. + {
  101. +     nfa_state_T *p = start;
  102. +     if (depth > 4)
  103. +     return 0;
  104. +     while (p != NULL)
  105. +     {
  106. +     switch (p->c)
  107. +     {
  108. +         /* all kinds of zero-width matches */
  109. +         case NFA_BOL:
  110. +         case NFA_BOF:
  111. +         case NFA_BOW:
  112. +         case NFA_EOW:
  113. +         case NFA_ZSTART:
  114. +         case NFA_ZEND:
  115. +         case NFA_CURSOR:
  116. +         case NFA_VISUAL:
  117. +         case NFA_LNUM:
  118. +         case NFA_LNUM_GT:
  119. +         case NFA_LNUM_LT:
  120. +         case NFA_COL:
  121. +         case NFA_COL_GT:
  122. +         case NFA_COL_LT:
  123. +         case NFA_VCOL:
  124. +         case NFA_VCOL_GT:
  125. +         case NFA_VCOL_LT:
  126. +         case NFA_MARK:
  127. +         case NFA_MARK_GT:
  128. +         case NFA_MARK_LT:
  129. +         case NFA_MOPEN:
  130. +         case NFA_MOPEN1:
  131. +         case NFA_MOPEN2:
  132. +         case NFA_MOPEN3:
  133. +         case NFA_MOPEN4:
  134. +         case NFA_MOPEN5:
  135. +         case NFA_MOPEN6:
  136. +         case NFA_MOPEN7:
  137. +         case NFA_MOPEN8:
  138. +         case NFA_MOPEN9:
  139. +         case NFA_NOPEN:
  140. + #ifdef FEAT_SYN_HL
  141. +         case NFA_ZOPEN:
  142. +         case NFA_ZOPEN1:
  143. +         case NFA_ZOPEN2:
  144. +         case NFA_ZOPEN3:
  145. +         case NFA_ZOPEN4:
  146. +         case NFA_ZOPEN5:
  147. +         case NFA_ZOPEN6:
  148. +         case NFA_ZOPEN7:
  149. +         case NFA_ZOPEN8:
  150. +         case NFA_ZOPEN9:
  151. + #endif
  152. +         p = p->out;
  153. +         break;
  154. +         case NFA_SPLIT:
  155. +         {
  156. +         int c1 = nfa_get_regstart(p->out, depth + 1);
  157. +         int c2 = nfa_get_regstart(p->out1, depth + 1);
  158. +         if (c1 == c2)
  159. +             return c1; /* yes! */
  160. +         return 0;
  161. +         }
  162. +         default:
  163. +         if (p->c > 0 && !p->negated)
  164. +             return p->c; /* yes! */
  165. +         return 0;
  166. +     }
  167. +     }
  168. +     return 0;
  169. + }
  170. + /*
  171.    * Allocate more space for post_start.  Called when
  172.    * running above the estimated number of states.
  173.    */
  174. ***************
  175. *** 2121,2126 ****
  176. --- 2272,2281 ----
  177.       if (debugf != NULL)
  178.       {
  179.       nfa_print_state(debugf, prog->start);
  180. +     fprintf(debugf, "reganch: %d\n", prog->reganch);
  181. +     fprintf(debugf, "regstart: %d\n", prog->regstart);
  182.       fclose(debugf);
  183.       }
  184.   }
  185. ***************
  186. *** 4248,4253 ****
  187. --- 4403,4412 ----
  188.           t = &neglist->t[0];
  189.           neglist->n--;
  190.           listidx--;
  191. + #ifdef ENABLE_LOG
  192. +         fprintf(log_fd, "     using neglist entry, %d remaining\n",
  193. +             neglist->n);
  194. + #endif
  195.           }
  196.           else
  197.           t = &thislist->t[listidx];
  198. ***************
  199. *** 4688,4694 ****
  200.   
  201.           case NFA_END_NEG_RANGE:
  202.           /* This follows a series of negated nodes, like:
  203. !          * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
  204.           if (curc > 0)
  205.           {
  206.               ll = nextlist;
  207. --- 4847,4853 ----
  208.   
  209.           case NFA_END_NEG_RANGE:
  210.           /* This follows a series of negated nodes, like:
  211. !          * NOT CHAR(x), NOT CHAR(y), etc. */
  212.           if (curc > 0)
  213.           {
  214.               ll = nextlist;
  215. ***************
  216. *** 5304,5316 ****
  217.    * Returns 0 for failure, number of lines contained in the match otherwise.
  218.    */
  219.       static long
  220. ! nfa_regexec_both(line, col)
  221.       char_u    *line;
  222. !     colnr_T    col;        /* column to start looking for match */
  223.   {
  224.       nfa_regprog_T   *prog;
  225.       long        retval = 0L;
  226.       int            i;
  227.   
  228.       if (REG_MULTI)
  229.       {
  230. --- 5463,5476 ----
  231.    * Returns 0 for failure, number of lines contained in the match otherwise.
  232.    */
  233.       static long
  234. ! nfa_regexec_both(line, startcol)
  235.       char_u    *line;
  236. !     colnr_T    startcol;    /* column to start looking for match */
  237.   {
  238.       nfa_regprog_T   *prog;
  239.       long        retval = 0L;
  240.       int            i;
  241. +     colnr_T        col = startcol;
  242.   
  243.       if (REG_MULTI)
  244.       {
  245. ***************
  246. *** 5333,5342 ****
  247.       goto theend;
  248.       }
  249.   
  250. -     /* If the start column is past the maximum column: no need to try. */
  251. -     if (ireg_maxcol > 0 && col >= ireg_maxcol)
  252. -     goto theend;
  253.       /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
  254.       if (prog->regflags & RF_ICASE)
  255.       ireg_ic = TRUE;
  256. --- 5493,5498 ----
  257. ***************
  258. *** 5361,5366 ****
  259. --- 5517,5548 ----
  260.       nfa_regengine.expr = prog->pattern;
  261.   #endif
  262.   
  263. +     if (prog->reganch && col > 0)
  264. +     return 0L;
  265. +     if (prog->regstart != NUL)
  266. +     {
  267. +     char_u *s;
  268. +     /* Skip until the char we know it must start with.
  269. +      * Used often, do some work to avoid call overhead. */
  270. +     if (!ireg_ic
  271. + #ifdef FEAT_MBYTE
  272. +             && !has_mbyte
  273. + #endif
  274. +             )
  275. +         s = vim_strbyte(regline + col, prog->regstart);
  276. +     else
  277. +         s = cstrchr(regline + col, prog->regstart);
  278. +     if (s == NULL)
  279. +         return 0L;
  280. +     col = (int)(s - regline);
  281. +     }
  282. +     /* If the start column is past the maximum column: no need to try. */
  283. +     if (ireg_maxcol > 0 && col >= ireg_maxcol)
  284. +     goto theend;
  285.       nstate = prog->nstate;
  286.       for (i = 0; i < nstate; ++i)
  287.       {
  288. ***************
  289. *** 5459,5464 ****
  290. --- 5641,5650 ----
  291.       prog->has_zend = nfa_has_zend;
  292.       prog->has_backref = nfa_has_backref;
  293.       prog->nsubexp = regnpar;
  294. +     prog->reganch = nfa_get_reganch(prog->start, 0);
  295. +     prog->regstart = nfa_get_regstart(prog->start, 0);
  296.   #ifdef ENABLE_LOG
  297.       nfa_postfix_dump(expr, OK);
  298.       nfa_dump(prog);
  299. *** ../vim-7.3.1132/src/regexp.h    2013-06-03 12:17:00.000000000 +0200
  300. --- src/regexp.h    2013-06-06 17:19:23.000000000 +0200
  301. ***************
  302. *** 87,92 ****
  303. --- 87,96 ----
  304.       unsigned        regflags;
  305.   
  306.       nfa_state_T        *start;        /* points into state[] */
  307. +     int            reganch;    /* pattern starts with ^ */
  308. +     int            regstart;    /* char at start of pattern */
  309.       int            has_zend;    /* pattern contains \ze */
  310.       int            has_backref;    /* pattern contains \1 .. \9 */
  311.   #ifdef FEAT_SYN_HL
  312. *** ../vim-7.3.1132/src/version.c    2013-06-06 18:04:47.000000000 +0200
  313. --- src/version.c    2013-06-06 18:43:55.000000000 +0200
  314. ***************
  315. *** 730,731 ****
  316. --- 730,733 ----
  317.   {   /* Add new patch number below this line */
  318. + /**/
  319. +     1133,
  320.   /**/
  321.  
  322. -- 
  323. From "know your smileys":
  324.  %    Bike accident.  A bit far-fetched, I suppose; although...
  325.              o      _     _         _
  326.      _o     /\_   _ \\o  (_)\__/o  (_)
  327.    _< \_   _>(_) (_)/<_    \_| \   _|/' \/
  328.   (_)>(_) (_)        (_)   (_)    (_)'  _\o_
  329.  
  330.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  331. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  332. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  333.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  334.