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.434 < prev    next >
Encoding:
Internet Message Format  |  2012-11-20  |  6.0 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.434
  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.434
  11. Problem:    Using join() can be slow.
  12. Solution:   Compute the size of the result before allocation to avoid a lot of
  13.             allocations and copies. (Taro Muraoka)
  14. Files:      src/eval.c
  15.  
  16.  
  17. *** ../vim-7.3.433/src/eval.c    2012-02-05 00:39:14.000000000 +0100
  18. --- src/eval.c    2012-02-06 00:05:31.000000000 +0100
  19. ***************
  20. *** 442,447 ****
  21. --- 442,448 ----
  22.   static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
  23.   static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
  24.   static char_u *list2string __ARGS((typval_T *tv, int copyID));
  25. + static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap));
  26.   static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
  27.   static int free_unref_items __ARGS((int copyID));
  28.   static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
  29. ***************
  30. *** 6571,6617 ****
  31.       return (char_u *)ga.ga_data;
  32.   }
  33.   
  34. ! /*
  35. !  * Join list "l" into a string in "*gap", using separator "sep".
  36. !  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
  37. !  * Return FAIL or OK.
  38. !  */
  39.       static int
  40. ! list_join(gap, l, sep, echo_style, copyID)
  41. !     garray_T    *gap;
  42.       list_T    *l;
  43.       char_u    *sep;
  44.       int        echo_style;
  45.       int        copyID;
  46.   {
  47.       int        first = TRUE;
  48.       char_u    *tofree;
  49.       char_u    numbuf[NUMBUFLEN];
  50.       listitem_T    *item;
  51.       char_u    *s;
  52.   
  53.       for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
  54.       {
  55. -     if (first)
  56. -         first = FALSE;
  57. -     else
  58. -         ga_concat(gap, sep);
  59.       if (echo_style)
  60.           s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
  61.       else
  62.           s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
  63. -     if (s != NULL)
  64. -         ga_concat(gap, s);
  65. -     vim_free(tofree);
  66.       if (s == NULL)
  67.           return FAIL;
  68.       line_breakcheck();
  69.       }
  70.       return OK;
  71.   }
  72.   
  73.   /*
  74.    * Garbage collection for lists and dictionaries.
  75.    *
  76.    * We use reference counts to be able to free most items right away when they
  77. --- 6572,6690 ----
  78.       return (char_u *)ga.ga_data;
  79.   }
  80.   
  81. ! typedef struct join_S {
  82. !     char_u    *s;
  83. !     char_u    *tofree;
  84. ! } join_T;
  85.       static int
  86. ! list_join_inner(gap, l, sep, echo_style, copyID, join_gap)
  87. !     garray_T    *gap;        /* to store the result in */
  88.       list_T    *l;
  89.       char_u    *sep;
  90.       int        echo_style;
  91.       int        copyID;
  92. +     garray_T    *join_gap;    /* to keep each list item string */
  93.   {
  94. +     int        i;
  95. +     join_T    *p;
  96. +     int        len;
  97. +     int        sumlen = 0;
  98.       int        first = TRUE;
  99.       char_u    *tofree;
  100.       char_u    numbuf[NUMBUFLEN];
  101.       listitem_T    *item;
  102.       char_u    *s;
  103.   
  104. +     /* Stringify each item in the list. */
  105.       for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
  106.       {
  107.       if (echo_style)
  108.           s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
  109.       else
  110.           s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
  111.       if (s == NULL)
  112.           return FAIL;
  113. +     len = (int)STRLEN(s);
  114. +     sumlen += len;
  115. +     ga_grow(join_gap, 1);
  116. +     p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
  117. +     if (tofree != NULL || s != numbuf)
  118. +     {
  119. +         p->s = s;
  120. +         p->tofree = tofree;
  121. +     }
  122. +     else
  123. +     {
  124. +         p->s = vim_strnsave(s, len);
  125. +         p->tofree = p->s;
  126. +     }
  127. +     line_breakcheck();
  128. +     }
  129. +     /* Allocate result buffer with its total size, avoid re-allocation and
  130. +      * multiple copy operations.  Add 2 for a tailing ']' and NUL. */
  131. +     if (join_gap->ga_len >= 2)
  132. +     sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
  133. +     if (ga_grow(gap, sumlen + 2) == FAIL)
  134. +     return FAIL;
  135. +     for (i = 0; i < join_gap->ga_len && !got_int; ++i)
  136. +     {
  137. +     if (first)
  138. +         first = FALSE;
  139. +     else
  140. +         ga_concat(gap, sep);
  141. +     p = ((join_T *)join_gap->ga_data) + i;
  142. +     if (p->s != NULL)
  143. +         ga_concat(gap, p->s);
  144.       line_breakcheck();
  145.       }
  146.       return OK;
  147.   }
  148.   
  149.   /*
  150. +  * Join list "l" into a string in "*gap", using separator "sep".
  151. +  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
  152. +  * Return FAIL or OK.
  153. +  */
  154. +     static int
  155. + list_join(gap, l, sep, echo_style, copyID)
  156. +     garray_T    *gap;
  157. +     list_T    *l;
  158. +     char_u    *sep;
  159. +     int        echo_style;
  160. +     int        copyID;
  161. + {
  162. +     garray_T    join_ga;
  163. +     int        retval;
  164. +     join_T    *p;
  165. +     int        i;
  166. +     ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
  167. +     retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
  168. +     /* Dispose each item in join_ga. */
  169. +     if (join_ga.ga_data != NULL)
  170. +     {
  171. +     p = (join_T *)join_ga.ga_data;
  172. +     for (i = 0; i < join_ga.ga_len; ++i)
  173. +     {
  174. +         vim_free(p->tofree);
  175. +         ++p;
  176. +     }
  177. +     ga_clear(&join_ga);
  178. +     }
  179. +     return retval;
  180. + }
  181. + /*
  182.    * Garbage collection for lists and dictionaries.
  183.    *
  184.    * We use reference counts to be able to free most items right away when they
  185. ***************
  186. *** 13406,13412 ****
  187.       char_u    *rhs;
  188.       int        mode;
  189.       int        abbr = FALSE;
  190. !     int         get_dict = FALSE;
  191.       mapblock_T    *mp;
  192.       int        buffer_local;
  193.   
  194. --- 13479,13485 ----
  195.       char_u    *rhs;
  196.       int        mode;
  197.       int        abbr = FALSE;
  198. !     int        get_dict = FALSE;
  199.       mapblock_T    *mp;
  200.       int        buffer_local;
  201.   
  202. *** ../vim-7.3.433/src/version.c    2012-02-05 23:10:25.000000000 +0100
  203. --- src/version.c    2012-02-06 00:10:23.000000000 +0100
  204. ***************
  205. *** 716,717 ****
  206. --- 716,719 ----
  207.   {   /* Add new patch number below this line */
  208. + /**/
  209. +     434,
  210.   /**/
  211.  
  212. -- 
  213. hundred-and-one symptoms of being an internet addict:
  214. 30. Even though you died last week, you've managed to retain OPS on your
  215.     favorite IRC channel.
  216.  
  217.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  218. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  219. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  220.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  221.