Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is faster: clear collection or instantiate new

I have some number of generic lists in my code, that have tens or hundreds elements. Sometimes I need to refill this lists with other objects, so question is: what will be faster, to call Clear() method or creating a new List<T>()?

like image 766
Mrimsh Avatar asked Jun 05 '12 16:06

Mrimsh


People also ask

Does list clear create a new list?

Actually, it will not create a new ArrayList in memory, instead it will replace the old list.

What does list clear do?

Definition and Usage The clear() method removes all the elements from a list.

How do you clear a list in C#?

To empty a C# list, use the Clear() method.


3 Answers

what will be faster, to call Clear() method or creating a `new List()?

This is impossible to answer. It really depends on a lot of factors, including how long the collection has existed.

The best option here would be to:

  1. Profile the application, and see if this really matters. It likely won't make any perceptible difference, in which case, I'd use the method that makes the most sense in terms of how you think of this object.

  2. If it does matter, write both sets of code, and measure the difference in speed (if any).

From a practical perspective, calling Clear() will not actually reduce the memory (used by the List<T> itself), as it doesn't shrink the list's capacity, only eliminates the values contained within it. Creating a new List<T> will cause a new list to be allocated, which will in turn cause more allocations with growth.

This, however, does not mean that it will be slower - in many cases, reallocating will be faster as you're less likely to promote the large arrays into higher garbage collection generations, which in turn can keep the GC process much faster.

Without knowing your exact scenario and measuring in a profiler, there is no way to know which is better in your scenario.

like image 80
Reed Copsey Avatar answered Oct 10 '22 10:10

Reed Copsey


I've run this test:

private static void Main(string[] args) {     int defaultN = 1000;      Stopwatch sw = new Stopwatch();      while (true)     {         Console.WriteLine("Enter test elements number:");         int n;         if (!int.TryParse(Console.ReadLine(), out n)) n = defaultN;         else defaultN = n;          Console.WriteLine($"Test with {n} elements");          List<object> list = Enumerable.Repeat(new object(), n).ToList();         sw.Start();         Clear(list);         sw.Stop();         Console.WriteLine("Clear: {0} ms", sw.ElapsedTicks / 10000D);          GC.Collect();         GC.WaitForPendingFinalizers();          List<object> list2 = Enumerable.Repeat(new object(), n).ToList();         sw.Restart();         Reinitialize(list2);         sw.Stop();         Console.WriteLine("Reinitialize: {0} ms", sw.ElapsedTicks / 10000D);          GC.Collect();         GC.WaitForPendingFinalizers();          List<object> list3 = Enumerable.Repeat(new object(), n).ToList();         sw.Restart();         ReinitializeAndCollect(list3);         sw.Stop();         Console.WriteLine("ReinitializeAndCollect: {0} ms", sw.ElapsedTicks / 10000D);          Console.WriteLine("===");     } } private static List<object> Clear(List<object> list) {     list.Clear();     return list; } private static List<object> Reinitialize(List<object> list) => new List<object>(); private static List<object> ReinitializeAndCollect(List<object> list) {     list = new List<object>();      GC.Collect();     GC.WaitForPendingFinalizers();      return list; } 

My conclusion based on a results of my ordinary core i3 processor:

In case of thousands of elements - it is better to clear list. It is fast and memory efficient.

If collection has more than 100 000 elements - reinitializing becomes more attractive. If after profiling you think that there is a bottleneck here, use it. Re-initialization will be very fast, but as third method test shows, future garbage collecting will be about as slow as just clearing the list.

So short answer is: if you didn't profiled your application, use Clear. Reusing objects is good. If you did - you already know what to do.

like image 37
astef Avatar answered Oct 10 '22 10:10

astef


This is going to depend on a lot of factors, and in the long run, it probably will not matter (enough to count) in your program.

From the msdn docs .Clear() is a O(n) operation.

Initializing a new instance will have its own overhead as well as (if you keep the collection the same length, a O(n) operation: i.e. n Add() calls).

Really the only way to test this is to set up some stopwatches in your program and see what the effect is if you really think it is worth it. In all likelihood; it's not worth it.

My thoughts would be that if you've already created a collection, Clear() it, that's why there is a Clear() method in the first place.

like image 23
NominSim Avatar answered Oct 10 '22 08:10

NominSim