-3

I am wondering what is faster.

list.Clear() or list = new List<..>()???

Which one leaves nice memory footprints?

What happens under the hood?

I am aware that both commands do two different things since the first one clears the list but doesnt destroy the instance and the second one frees the old instance but initalizes new one though in the end the result is the same and that is to get rid of items.

snowy hedgehog
  • 652
  • 1
  • 7
  • 23
  • vote up for the need for speed lol – Joe Slater Jun 06 '13 at 08:01
  • 10
    Given that they do different things, which *behaviour* are you actually after? Do you have any evidence of a *need* to improve the speed of this? – Jon Skeet Jun 06 '13 at 08:01
  • Change the topic name please... – Marek Jun 06 '13 at 08:02
  • @JonSkeet I am just wondering what is smoother faster and nicer. – snowy hedgehog Jun 06 '13 at 08:02
  • 3
    The only measurable thing in "smoother, faster and nicer" is "faster". Measure it. – CodeCaster Jun 06 '13 at 08:03
  • 3
    @Marek chill mate. it's nice to have something funny once in a while. – Joe Slater Jun 06 '13 at 08:03
  • 3
    Since `List.Clear` is O(n), I guess it depends on how big the list is: http://msdn.microsoft.com/en-us/library/dwb5h52a.aspx – Ant P Jun 06 '13 at 08:04
  • You are almost certainly better off creating a new list and letting the garbage collector deal with the old one. – Matthew Watson Jun 06 '13 at 08:06
  • It may be a C++ matter, but `new List()` creates a new list (allocates a new memory space and leaves the old one for the GC) while `Clear()` does in-place clearing . – Fares Jun 06 '13 at 08:07
  • There are already multiple questions on SO with exact this topic. For example: http://stackoverflow.com/questions/10901020/what-is-faster-in-c-clear-collection-or-instantiate-new or http://stackoverflow.com/questions/3106537/using-the-clear-method-vs-new-object – Tim Schmelter Jun 06 '13 at 08:07
  • 1
    Of course it is funny but by doing that no one will find probable answers for your questions in the future.. – Marek Jun 06 '13 at 08:08
  • If you intend to re-fill the List, then it's not just the clearing cost you need to consider, but the cost of putting items back in. A new List will need multiple re-allocation to put in large numbers of items, but a Cleared List has the capacity from the start (unless you call [TrimExcess](http://msdn.microsoft.com/en-us/library/ms132207(v=vs.80).aspx), but that's not necessary unless memory is a _real_ concern if you are going to re-use the list of a similar number of items as before). You do need to work out what the List will be used for before considering performance. – VisualMelon Jun 06 '13 at 08:08

3 Answers3

9

Here's how List.Clear is implemented (according to MSDN):

Count is set to 0, and references to other objects from elements of the collection are also released.

Capacity remains unchanged. To reset the capacity of the List, call the TrimExcess method or set the Capacity property directly. Decreasing the capacity reallocates memory and copies all the elements in the List. Trimming an empty List sets the capacity of the List to the default capacity.

This method is an O(n) operation, where n is Count.

Since Clear is O(n) and instantiating a new list is O(1), reinstantiating is likely to be quicker for large lists (and the difference is likely to be negligible for short ones).

Of course, since (as you already know) they function differently, you should pick the one that actually does what you want.

Ant P
  • 24,820
  • 5
  • 68
  • 105
  • 2
    If you compare use to Clear, you should probably also consider the runtime complexity of destruction/finalization of the old list. It's not free. In addition, if the list is used for a same number of elements, the pre-allocated capacity is probably advantageous. – Wilbert Jun 06 '13 at 08:11
  • Good point - do you know what the complexity of destruction of a List is? I guess an important distinction is that the old list won't necessarily be garbage collected immediately and won't hold up program execution like calling `Clear` would. – Ant P Jun 06 '13 at 08:17
2

The new operator will allocate memory in a managed heap. If the list was the only root to the previous list, this memory will be reclaimed during the next GC (whose execution is not really predictable unless you explicitly call GC.Collect which I wouldn't).

The List.Clear internally makes a call to Array.Clear which I guess just sets all bits to 0 in the destination array. This must be faster but I'm not sure about memory efficiency since it will probably depend on a particular case (in case you have a huge list which you're going to use only partially after the new operator, I think, it would be better to just release the old memory and let the list grow dynamically in size instead).

volpav
  • 5,090
  • 19
  • 27
2

One thing to consider when creating a new list is that in other places, references to the list may also be held. If you create a new list, those references won't change and the code will refer to the old list.

Clearing the list using Clear is safer in this case, as all places referencing the list will work with the cleared list now.

Example:

List<...> myGlobalList = new List<...>();
...

SomeWorkerClass wc = new SomeWorkerClass(myGlobalList);
myGlobalList = new List<...>();

wc will still use the original list and not the new instance of myGlobalList.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139