I’ve spotted some really nasty code in one class (let’s call it MyClass) that uses List of T.Add/Remove methods extensively. Also the same class exposes that collection as property with IList of T type, so changing the type would involve some refactoring.
Also, that MyClass collection is used as a container for event listener objects, so client code just subscribes (adds itself to collection) and unsubscribes (removes itself from collection). Order doesn’t matter, whether it’s start/middle/end of the list.
In order to improve performance, I would like to replace internal implementation detail, replace List of T with…. I don’t know what. I tried LinkedList of T, but it does not implement IList of T. I looked at IList of T at MSDN, but there’s no list of classes that implement IList, so I could compare documentations.
Another thing is that I tried to change IList of T to ICollection of T, and that could be a solution (as client code of MyClass uses Add/Remove methods, so no refactoring is necessary) but interesting thing happened:
LinkedList<string> list = new LinkedList<string>();
list.Add("test");
This code does not compile as I get an error:
‘System.Collections.Generic.LinkedList’ does not contain a
definition for ‘Add’ and no extension method ‘Add’
But when I changed it to:
ICollection<string> list = new LinkedList<string>();
list.Add("test");
then I worked. Could you explain why first sample didn’t compile + tell what is the fastest implementation of IList of T in .NET Framework in terms of Adding/Removing items?
Thanks.
There is no one single class that is fastest at adding and removing. They are all built to be faster in certain circumstances, and they all have their drawbacks as well.
Listcan quickly add to the end, most of the time, but it will periodically have an expensive add that involves copying every element. As you start adding items closer to the start it gets more and more expensive. Removing is cheap at the end, and more and more expensive as you move towards the start.LinkedListcan efficiently add to the start or end, but those adds are still quite a bit slower than adding to the end of aList(but without any really large adds). Adding to positions other than the start or end of aLinkedListget expensive quick. In most practical situations,LinkedListisn’t a good option from the perspective of performance.I could go on, but it would be a while. The point remains that we need to know more details about how the collection is being used in order to suggest a more performant alternative (or a different way of using the existing collection).
Since you have described that what you have is just a set of data that doesn’t need to be ordered and just need to efficiently add/remove/iterate all the best collection would be a
HashSet<T>. You can do some research yourself on the inner workings of a hash based data structure (it’s fairly cool) but the point is that it is an unordered data structure with extremely efficient adding/removing of elements, and that you can efficiently iterate. This is ideal for your circumstances. The one thing to keep in mind with a hash based data structure is that your objects need to have implementations ofGetHashCodeandEqualsthat are meaningful (the default ones usually aren’t for your custom types). If you’re using something likeintorstringas the key it will already have good implementations.