mirror of
https://github.com/zoriya/vim.git
synced 2025-12-20 06:05:18 +00:00
patch 8.2.0751: Vim9: performance can be improved
Problem: Vim9: performance can be improved.
Solution: Don't call break. Inline check for list materialize. Make an
inline version of ga_grow().
This commit is contained in:
@@ -2399,7 +2399,7 @@ channel_get_json(
|
||||
list_T *l = item->jq_value->vval.v_list;
|
||||
typval_T *tv;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
tv = &l->lv_first->li_tv;
|
||||
|
||||
if ((without_callback || !item->jq_no_callback)
|
||||
@@ -5302,7 +5302,7 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
range_list_materialize(item->vval.v_list);
|
||||
CHECK_LIST_MATERIALIZE(item->vval.v_list);
|
||||
li = item->vval.v_list->lv_first;
|
||||
for (; li != NULL && n < 16; li = li->li_next, n++)
|
||||
{
|
||||
@@ -5729,7 +5729,7 @@ win32_build_cmd(list_T *l, garray_T *gap)
|
||||
listitem_T *li;
|
||||
char_u *s;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
FOR_ALL_LIST_ITEMS(l, li)
|
||||
{
|
||||
s = tv_get_string_chk(&li->li_tv);
|
||||
|
||||
@@ -1449,7 +1449,7 @@ eval_for_line(
|
||||
else
|
||||
{
|
||||
// Need a real list here.
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
|
||||
// No need to increment the refcount, it's already set for
|
||||
// the list being used in "tv".
|
||||
|
||||
@@ -183,7 +183,7 @@ set_buffer_lines(
|
||||
rettv->vval.v_number = 1; // FAIL
|
||||
goto done;
|
||||
}
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
li = l->lv_first;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -2275,7 +2275,7 @@ execute_common(typval_T *argvars, typval_T *rettv, int arg_off)
|
||||
{
|
||||
listitem_T *item;
|
||||
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
item = list->lv_first;
|
||||
do_cmdline(NULL, get_list_line, (void *)&item,
|
||||
DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
|
||||
@@ -2820,7 +2820,7 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
|
||||
copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
|
||||
if (lv_len > 0)
|
||||
{
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
FOR_ALL_LIST_ITEMS(list, li)
|
||||
copy_tv(&li->li_tv, &pt->pt_argv[i++]);
|
||||
}
|
||||
@@ -4912,7 +4912,7 @@ f_index(typval_T *argvars, typval_T *rettv)
|
||||
l = argvars[0].vval.v_list;
|
||||
if (l != NULL)
|
||||
{
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
item = l->lv_first;
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
@@ -5018,7 +5018,7 @@ f_inputlist(typval_T *argvars, typval_T *rettv)
|
||||
msg_clr_eos();
|
||||
|
||||
l = argvars[0].vval.v_list;
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
FOR_ALL_LIST_ITEMS(l, li)
|
||||
{
|
||||
msg_puts((char *)tv_get_string(&li->li_tv));
|
||||
@@ -5494,7 +5494,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type)
|
||||
{
|
||||
if ((l = argvars[0].vval.v_list) == NULL)
|
||||
goto theend;
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
li = l->lv_first;
|
||||
}
|
||||
else
|
||||
@@ -6279,7 +6279,7 @@ f_range(typval_T *argvars, typval_T *rettv)
|
||||
list_T *list = rettv->vval.v_list;
|
||||
|
||||
// Create a non-materialized list. This is much more efficient and
|
||||
// works with ":for". If used otherwise range_list_materialize() must
|
||||
// works with ":for". If used otherwise CHECK_LIST_MATERIALIZE() must
|
||||
// be called.
|
||||
list->lv_first = &range_list_item;
|
||||
list->lv_u.nonmat.lv_start = start;
|
||||
@@ -6290,13 +6290,12 @@ f_range(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
|
||||
/*
|
||||
* If "list" is a non-materialized list then materialize it now.
|
||||
* Materialize "list".
|
||||
* Do not call directly, use CHECK_LIST_MATERIALIZE()
|
||||
*/
|
||||
void
|
||||
range_list_materialize(list_T *list)
|
||||
{
|
||||
if (list->lv_first == &range_list_item)
|
||||
{
|
||||
varnumber_T start = list->lv_u.nonmat.lv_start;
|
||||
varnumber_T end = list->lv_u.nonmat.lv_end;
|
||||
int stride = list->lv_u.nonmat.lv_stride;
|
||||
@@ -6309,7 +6308,6 @@ range_list_materialize(list_T *list)
|
||||
for (i = start; stride > 0 ? i <= end : i >= end; i += stride)
|
||||
if (list_append_number(list, (varnumber_T)i) == FAIL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -7327,7 +7325,7 @@ f_setreg(typval_T *argvars, typval_T *rettv)
|
||||
|
||||
if (ll != NULL)
|
||||
{
|
||||
range_list_materialize(ll);
|
||||
CHECK_LIST_MATERIALIZE(ll);
|
||||
FOR_ALL_LIST_ITEMS(ll, li)
|
||||
{
|
||||
strval = tv_get_string_buf_chk(&li->li_tv, buf);
|
||||
|
||||
@@ -863,7 +863,7 @@ ex_let_vars(
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
item = l->lv_first;
|
||||
while (*arg != ']')
|
||||
{
|
||||
|
||||
@@ -1917,7 +1917,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
|
||||
list = argvars[0].vval.v_list;
|
||||
if (list == NULL)
|
||||
return;
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
FOR_ALL_LIST_ITEMS(list, li)
|
||||
if (tv_get_string_chk(&li->li_tv) == NULL)
|
||||
return;
|
||||
|
||||
@@ -3743,7 +3743,7 @@ match_add(
|
||||
listitem_T *li;
|
||||
int i;
|
||||
|
||||
range_list_materialize(pos_list);
|
||||
CHECK_LIST_MATERIALIZE(pos_list);
|
||||
for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
|
||||
i++, li = li->li_next)
|
||||
{
|
||||
|
||||
@@ -785,7 +785,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
FOR_ALL_LIST_ITEMS(list, curr)
|
||||
{
|
||||
if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
|
||||
@@ -2256,7 +2256,7 @@ ListNew(PyTypeObject *subtype, list_T *list)
|
||||
return NULL;
|
||||
self->list = list;
|
||||
++list->lv_refcount;
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
|
||||
pyll_add((PyObject *)(self), &self->ref, &lastlist);
|
||||
|
||||
@@ -2824,7 +2824,7 @@ ListIter(ListObject *self)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
list_add_watch(l, &lii->lw);
|
||||
lii->lw.lw_item = l->lv_first;
|
||||
lii->list = l;
|
||||
@@ -3021,7 +3021,7 @@ FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
|
||||
return NULL;
|
||||
}
|
||||
argslist = argstv.vval.v_list;
|
||||
range_list_materialize(argslist);
|
||||
CHECK_LIST_MATERIALIZE(argslist);
|
||||
|
||||
argc = argslist->lv_len;
|
||||
if (argc != 0)
|
||||
|
||||
@@ -2334,7 +2334,7 @@ ins_compl_add_list(list_T *list)
|
||||
int dir = compl_direction;
|
||||
|
||||
// Go through the List with matches and add each of them.
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
FOR_ALL_LIST_ITEMS(list, li)
|
||||
{
|
||||
if (ins_compl_add_tv(&li->li_tv, dir) == OK)
|
||||
@@ -2519,7 +2519,7 @@ get_complete_info(list_T *what_list, dict_T *retdict)
|
||||
else
|
||||
{
|
||||
what_flag = 0;
|
||||
range_list_materialize(what_list);
|
||||
CHECK_LIST_MATERIALIZE(what_list);
|
||||
FOR_ALL_LIST_ITEMS(what_list, item)
|
||||
{
|
||||
char_u *what = tv_get_string(&item->li_tv);
|
||||
|
||||
@@ -265,7 +265,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
|
||||
|
||||
l->lv_copyID = copyID;
|
||||
ga_append(gap, '[');
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
for (li = l->lv_first; li != NULL && !got_int; )
|
||||
{
|
||||
if (json_encode_item(gap, &li->li_tv, copyID,
|
||||
|
||||
34
src/list.c
34
src/list.c
@@ -378,8 +378,8 @@ list_equal(
|
||||
if (l1 == NULL || l2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
range_list_materialize(l1);
|
||||
range_list_materialize(l2);
|
||||
CHECK_LIST_MATERIALIZE(l1);
|
||||
CHECK_LIST_MATERIALIZE(l2);
|
||||
|
||||
for (item1 = l1->lv_first, item2 = l2->lv_first;
|
||||
item1 != NULL && item2 != NULL;
|
||||
@@ -411,7 +411,7 @@ list_find(list_T *l, long n)
|
||||
if (n < 0 || n >= l->lv_len)
|
||||
return NULL;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
|
||||
// When there is a cached index may start search from there.
|
||||
if (l->lv_u.mat.lv_idx_item != NULL)
|
||||
@@ -541,7 +541,7 @@ list_idx_of_item(list_T *l, listitem_T *item)
|
||||
|
||||
if (l == NULL)
|
||||
return -1;
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
idx = 0;
|
||||
for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
|
||||
++idx;
|
||||
@@ -556,7 +556,7 @@ list_idx_of_item(list_T *l, listitem_T *item)
|
||||
void
|
||||
list_append(list_T *l, listitem_T *item)
|
||||
{
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
if (l->lv_u.mat.lv_last == NULL)
|
||||
{
|
||||
// empty list
|
||||
@@ -706,7 +706,7 @@ list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
|
||||
void
|
||||
list_insert(list_T *l, listitem_T *ni, listitem_T *item)
|
||||
{
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
if (item == NULL)
|
||||
// Append new item at end of list.
|
||||
list_append(l, ni);
|
||||
@@ -741,8 +741,8 @@ list_extend(list_T *l1, list_T *l2, listitem_T *bef)
|
||||
listitem_T *item;
|
||||
int todo = l2->lv_len;
|
||||
|
||||
range_list_materialize(l1);
|
||||
range_list_materialize(l2);
|
||||
CHECK_LIST_MATERIALIZE(l1);
|
||||
CHECK_LIST_MATERIALIZE(l2);
|
||||
|
||||
// We also quit the loop when we have inserted the original item count of
|
||||
// the list, avoid a hang when we extend a list with itself.
|
||||
@@ -801,7 +801,7 @@ list_copy(list_T *orig, int deep, int copyID)
|
||||
orig->lv_copyID = copyID;
|
||||
orig->lv_copylist = copy;
|
||||
}
|
||||
range_list_materialize(orig);
|
||||
CHECK_LIST_MATERIALIZE(orig);
|
||||
for (item = orig->lv_first; item != NULL && !got_int;
|
||||
item = item->li_next)
|
||||
{
|
||||
@@ -842,7 +842,7 @@ vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
|
||||
{
|
||||
listitem_T *ip;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
|
||||
// notify watchers
|
||||
for (ip = item; ip != NULL; ip = ip->li_next)
|
||||
@@ -877,7 +877,7 @@ list2string(typval_T *tv, int copyID, int restore_copyID)
|
||||
return NULL;
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
ga_append(&ga, '[');
|
||||
range_list_materialize(tv->vval.v_list);
|
||||
CHECK_LIST_MATERIALIZE(tv->vval.v_list);
|
||||
if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
|
||||
FALSE, restore_copyID, copyID) == FAIL)
|
||||
{
|
||||
@@ -915,7 +915,7 @@ list_join_inner(
|
||||
char_u *s;
|
||||
|
||||
// Stringify each item in the list.
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
|
||||
{
|
||||
s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
|
||||
@@ -1116,7 +1116,7 @@ write_list(FILE *fd, list_T *list, int binary)
|
||||
int ret = OK;
|
||||
char_u *s;
|
||||
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
FOR_ALL_LIST_ITEMS(list, li)
|
||||
{
|
||||
for (s = tv_get_string(&li->li_tv); *s != NUL; ++s)
|
||||
@@ -1203,7 +1203,7 @@ f_list2str(typval_T *argvars, typval_T *rettv)
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
utf8 = (int)tv_get_number_chk(&argvars[1], NULL);
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
ga_init2(&ga, 1, 80);
|
||||
if (has_mbyte || utf8)
|
||||
{
|
||||
@@ -1496,7 +1496,7 @@ do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
|
||||
TRUE))
|
||||
goto theend;
|
||||
rettv_list_set(rettv, l);
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
|
||||
len = list_len(l);
|
||||
if (len <= 1)
|
||||
@@ -1873,7 +1873,7 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
|
||||
// set_vim_var_nr() doesn't set the type
|
||||
set_vim_var_type(VV_KEY, VAR_NUMBER);
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
if (map && l->lv_lock == 0)
|
||||
l->lv_lock = VAR_LOCKED;
|
||||
for (li = l->lv_first; li != NULL; li = nli)
|
||||
@@ -2011,7 +2011,7 @@ f_count(typval_T *argvars, typval_T *rettv)
|
||||
|
||||
if ((l = argvars[0].vval.v_list) != NULL)
|
||||
{
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
li = l->lv_first;
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
|
||||
@@ -373,3 +373,9 @@
|
||||
# define ESTACK_CHECK_NOW
|
||||
# define CHECK_CURBUF
|
||||
#endif
|
||||
|
||||
// Inline the condition for performance.
|
||||
#define CHECK_LIST_MATERIALIZE(l) if ((l)->lv_first == &range_list_item) range_list_materialize(l)
|
||||
|
||||
// Inlined version of ga_grow(). Especially useful if "n" is a constant.
|
||||
#define GA_GROW(gap, n) (((gap)->ga_maxlen - (gap)->ga_len < n) ? ga_grow_inner((gap), (n)) : OK)
|
||||
|
||||
11
src/misc2.c
11
src/misc2.c
@@ -2053,13 +2053,19 @@ ga_init2(garray_T *gap, int itemsize, int growsize)
|
||||
*/
|
||||
int
|
||||
ga_grow(garray_T *gap, int n)
|
||||
{
|
||||
if (gap->ga_maxlen - gap->ga_len < n)
|
||||
return ga_grow_inner(gap, n);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
ga_grow_inner(garray_T *gap, int n)
|
||||
{
|
||||
size_t old_len;
|
||||
size_t new_len;
|
||||
char_u *pp;
|
||||
|
||||
if (gap->ga_maxlen - gap->ga_len < n)
|
||||
{
|
||||
if (n < gap->ga_growsize)
|
||||
n = gap->ga_growsize;
|
||||
|
||||
@@ -2077,7 +2083,6 @@ ga_grow(garray_T *gap, int n)
|
||||
vim_memset(pp + old_len, 0, new_len - old_len);
|
||||
gap->ga_maxlen = gap->ga_len + n;
|
||||
gap->ga_data = pp;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1318,7 +1318,7 @@ ui_post_balloon(char_u *mesg, list_T *list)
|
||||
balloon_array = ALLOC_CLEAR_MULT(pumitem_T, list->lv_len);
|
||||
if (balloon_array == NULL)
|
||||
return;
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
for (idx = 0, li = list->lv_first; li != NULL; li = li->li_next, ++idx)
|
||||
{
|
||||
char_u *text = tv_get_string_chk(&li->li_tv);
|
||||
|
||||
@@ -98,7 +98,7 @@ set_padding_border(dict_T *dict, int *array, char *name, int max_val)
|
||||
array[i] = 1;
|
||||
if (list != NULL)
|
||||
{
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
|
||||
++i, li = li->li_next)
|
||||
{
|
||||
@@ -516,7 +516,7 @@ handle_moved_argument(win_T *wp, dictitem_T *di, int mousemoved)
|
||||
int mincol;
|
||||
int maxcol;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
li = l->lv_first;
|
||||
if (l->lv_len == 3)
|
||||
{
|
||||
@@ -756,7 +756,7 @@ apply_general_options(win_T *wp, dict_T *dict)
|
||||
listitem_T *li;
|
||||
int i;
|
||||
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
|
||||
++i, li = li->li_next)
|
||||
{
|
||||
@@ -790,7 +790,7 @@ apply_general_options(win_T *wp, dict_T *dict)
|
||||
|
||||
if (list != NULL)
|
||||
{
|
||||
range_list_materialize(list);
|
||||
CHECK_LIST_MATERIALIZE(list);
|
||||
for (i = 0, li = list->lv_first; i < 8 && i < list->lv_len;
|
||||
++i, li = li->li_next)
|
||||
{
|
||||
@@ -845,7 +845,7 @@ apply_general_options(win_T *wp, dict_T *dict)
|
||||
break;
|
||||
}
|
||||
else
|
||||
range_list_materialize(li->li_tv.vval.v_list);
|
||||
CHECK_LIST_MATERIALIZE(li->li_tv.vval.v_list);
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
|
||||
@@ -59,6 +59,7 @@ void ga_clear_strings(garray_T *gap);
|
||||
void ga_init(garray_T *gap);
|
||||
void ga_init2(garray_T *gap, int itemsize, int growsize);
|
||||
int ga_grow(garray_T *gap, int n);
|
||||
int ga_grow_inner(garray_T *gap, int n);
|
||||
char_u *ga_concat_strings(garray_T *gap, char *sep);
|
||||
void ga_add_string(garray_T *gap, char_u *p);
|
||||
void ga_concat(garray_T *gap, char_u *s);
|
||||
|
||||
@@ -1718,7 +1718,7 @@ func_call(
|
||||
int argc = 0;
|
||||
int r = 0;
|
||||
|
||||
range_list_materialize(l);
|
||||
CHECK_LIST_MATERIALIZE(l);
|
||||
FOR_ALL_LIST_ITEMS(l, item)
|
||||
{
|
||||
if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
|
||||
|
||||
Reference in New Issue
Block a user