comparison src/list.c @ 23037:4ba6c5eebb28 v8.2.2065

patch 8.2.2065: using map() and filter() on a range() is inefficient Commit: https://github.com/vim/vim/commit/f8ca03bf9161ab9ee1a29db1d13c02b317c10029 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Nov 28 20:32:29 2020 +0100 patch 8.2.2065: using map() and filter() on a range() is inefficient Problem: Using map() and filter() on a range() is inefficient. Solution: Do not materialize the range. (closes https://github.com/vim/vim/issues/7388)
author Bram Moolenaar <Bram@vim.org>
date Sat, 28 Nov 2020 20:45:04 +0100
parents 6426acc72539
children 77f181975381
comparison
equal deleted inserted replaced
23036:58487aedb0c3 23037:4ba6c5eebb28
2171 l_ret = rettv->vval.v_list; 2171 l_ret = rettv->vval.v_list;
2172 } 2172 }
2173 // set_vim_var_nr() doesn't set the type 2173 // set_vim_var_nr() doesn't set the type
2174 set_vim_var_type(VV_KEY, VAR_NUMBER); 2174 set_vim_var_type(VV_KEY, VAR_NUMBER);
2175 2175
2176 CHECK_LIST_MATERIALIZE(l);
2177 if (filtermap != FILTERMAP_FILTER && l->lv_lock == 0) 2176 if (filtermap != FILTERMAP_FILTER && l->lv_lock == 0)
2178 l->lv_lock = VAR_LOCKED; 2177 l->lv_lock = VAR_LOCKED;
2179 for (li = l->lv_first; li != NULL; li = nli) 2178
2180 { 2179 if (l->lv_first == &range_list_item)
2181 typval_T newtv; 2180 {
2182 2181 varnumber_T val = l->lv_u.nonmat.lv_start;
2183 if (filtermap != FILTERMAP_FILTER 2182 int len = l->lv_len;
2184 && value_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) 2183 int stride = l->lv_u.nonmat.lv_stride;
2185 break; 2184
2186 nli = li->li_next; 2185 // List from range(): loop over the numbers
2187 set_vim_var_nr(VV_KEY, idx); 2186 l->lv_first = NULL;
2188 if (filter_map_one(&li->li_tv, expr, filtermap, 2187 l->lv_u.mat.lv_last = NULL;
2189 &newtv, &rem) == FAIL) 2188 l->lv_len = 0;
2190 break; 2189 l->lv_u.mat.lv_idx_item = NULL;
2191 if (did_emsg) 2190
2191 for (idx = 0; idx < len; ++idx)
2192 { 2192 {
2193 clear_tv(&newtv); 2193 typval_T tv;
2194 break; 2194 typval_T newtv;
2195
2196 tv.v_type = VAR_NUMBER;
2197 tv.v_lock = 0;
2198 tv.vval.v_number = val;
2199 set_vim_var_nr(VV_KEY, idx);
2200 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem)
2201 == FAIL)
2202 break;
2203 if (did_emsg)
2204 {
2205 clear_tv(&newtv);
2206 break;
2207 }
2208 if (filtermap != FILTERMAP_FILTER)
2209 {
2210 // map(), mapnew(): always append the new value to the
2211 // list
2212 if (list_append_tv_move(filtermap == FILTERMAP_MAP
2213 ? l : l_ret, &newtv) == FAIL)
2214 break;
2215 }
2216 else if (!rem)
2217 {
2218 // filter(): append the list item value when not rem
2219 if (list_append_tv_move(l, &tv) == FAIL)
2220 break;
2221 }
2222
2223 val += stride;
2195 } 2224 }
2196 if (filtermap == FILTERMAP_MAP) 2225 }
2226 else
2227 {
2228 // Materialized list from range(): loop over the items
2229 for (li = l->lv_first; li != NULL; li = nli)
2197 { 2230 {
2198 // map(): replace the list item value 2231 typval_T newtv;
2199 clear_tv(&li->li_tv); 2232
2200 newtv.v_lock = 0; 2233 if (filtermap != FILTERMAP_FILTER && value_check_lock(
2201 li->li_tv = newtv; 2234 li->li_tv.v_lock, arg_errmsg, TRUE))
2235 break;
2236 nli = li->li_next;
2237 set_vim_var_nr(VV_KEY, idx);
2238 if (filter_map_one(&li->li_tv, expr, filtermap,
2239 &newtv, &rem) == FAIL)
2240 break;
2241 if (did_emsg)
2242 {
2243 clear_tv(&newtv);
2244 break;
2245 }
2246 if (filtermap == FILTERMAP_MAP)
2247 {
2248 // map(): replace the list item value
2249 clear_tv(&li->li_tv);
2250 newtv.v_lock = 0;
2251 li->li_tv = newtv;
2252 }
2253 else if (filtermap == FILTERMAP_MAPNEW)
2254 {
2255 // mapnew(): append the list item value
2256 if (list_append_tv_move(l_ret, &newtv) == FAIL)
2257 break;
2258 }
2259 else if (filtermap == FILTERMAP_FILTER && rem)
2260 listitem_remove(l, li);
2261 ++idx;
2202 } 2262 }
2203 else if (filtermap == FILTERMAP_MAPNEW) 2263 }
2204 { 2264
2205 // mapnew(): append the list item value
2206 if (list_append_tv_move(l_ret, &newtv) == FAIL)
2207 break;
2208 }
2209 else if (filtermap == FILTERMAP_FILTER && rem)
2210 listitem_remove(l, li);
2211 ++idx;
2212 }
2213 l->lv_lock = prev_lock; 2265 l->lv_lock = prev_lock;
2214 } 2266 }
2215 2267
2216 restore_vimvar(VV_KEY, &save_key); 2268 restore_vimvar(VV_KEY, &save_key);
2217 restore_vimvar(VV_VAL, &save_val); 2269 restore_vimvar(VV_VAL, &save_val);