Skip to content

Commit

Permalink
Remove O(N) List<T>.RemoveAt from RegexCache.Add (dotnet#106581)
Browse files Browse the repository at this point in the history
The cache maintains a list of all regexes in the cache, which it uses to be able to randomly access members as part of evicting when the cache is full and an item needs to be replaced. When evicting, it randomly samples a subset of the items, and then removes whichever is found to have the oldest timestamp. That RemoveAt call is O(N), as elements need to be shifted down. But the order of the list doesn't actually matter, so we can make that instead be O(1) by just moving the last element into the removal slot (overwriting the one to be removed) and then shrinking the size of the list.
  • Loading branch information
stephentoub committed Sep 1, 2024
1 parent 30895ac commit ffd3b18
Showing 1 changed file with 5 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,12 @@ private static void Add(Key key, Regex regex)
}
}

// Remove the key found to have the smallest access stamp.
// Remove the key found to have the smallest access stamp. List ordering isn't important, so rather than
// just removing the element at minListIndex, which would result in an O(N) shift down, we copy the last
// element to minListIndex, and then remove the last. (If minListIndex is the last, this is a no-op.)
s_cacheDictionary.TryRemove(s_cacheList[minListIndex].Key, out _);
s_cacheList.RemoveAt(minListIndex);
s_cacheList[minListIndex] = s_cacheList[^1];
s_cacheList.RemoveAt(s_cacheList.Count - 1);
}

// Finally add the regex.
Expand Down

0 comments on commit ffd3b18

Please sign in to comment.