patch 9.0.0622: matchaddpos() can get slow when adding many matches
Problem: matchaddpos() can get slow when adding many matches.
Solution: Update the next available match ID when manually picking an ID and
remove check if the available ID can be used. (idea by Rick Howe)
diff --git a/src/match.c b/src/match.c
index ecab28c..ceb317c 100644
--- a/src/match.c
+++ b/src/match.c
@@ -50,19 +50,28 @@
semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_1), id);
return -1;
}
- if (id != -1)
+ if (id == -1)
{
- cur = wp->w_match_head;
- while (cur != NULL)
- {
+ // use the next available match ID
+ id = wp->w_next_match_id++;
+ }
+ else
+ {
+ // check the given ID is not already in use
+ for (cur = wp->w_match_head; cur != NULL; cur = cur->mit_next)
if (cur->mit_id == id)
{
semsg(_(e_id_already_taken_nr), id);
return -1;
}
- cur = cur->mit_next;
- }
+
+ // Make sure the next match ID is always higher than the highest
+ // manually selected ID. Add some extra in case a few more IDs are
+ // added soon.
+ if (wp->w_next_match_id < id + 100)
+ wp->w_next_match_id = id + 100;
}
+
if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
{
semsg(_(e_no_such_highlight_group_name_str), grp);
@@ -74,17 +83,6 @@
return -1;
}
- // Find available match ID.
- while (id == -1)
- {
- cur = wp->w_match_head;
- while (cur != NULL && cur->mit_id != wp->w_next_match_id)
- cur = cur->mit_next;
- if (cur == NULL)
- id = wp->w_next_match_id;
- wp->w_next_match_id++;
- }
-
// Build new match.
m = ALLOC_CLEAR_ONE(matchitem_T);
if (m == NULL)