7

Consider the following code:

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ListAllocationPerformance
{
    class Program
    {
        const int count = 100000000;

        public static object Memory { get; private set; }

        static void Main(string[] args)
        {
            Console.WriteLine(string.Format("count: {0}", count));
            MeasureFunction(FillListWithoutAllocation, "without allocation");
            MeasureFunction(FillListWithAllocation, "with allocation");
            MeasureFunction(FillArray, "array");
            MeasureFunction(FillUnmanagedArray, "unsafe array");
            string input = Console.ReadLine();
        }

        static void MeasureFunction(Action function, string name)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            function();
            stopwatch.Stop();
            Console.WriteLine(string.Format("Function {0} finished after \t {1}ms", name, stopwatch.ElapsedMilliseconds, count));
        }

        static void FillListWithoutAllocation()
        {
            List<int> list = new List<int>();
            for (int i = 0; i < count; i++) list.Add(i);
        }

        static void FillListWithAllocation()
        {
            List<int> list = new List<int>(count);
            for (int i = 0; i < count; i++) list.Add(i);
        }

        static void FillArray()
        {
            int[] array = new int[count];
            for (int i = 0; i < count; i++) array[i] = i;
        }

        static void FillUnmanagedArray()
        {
            unsafe
            {
                int[] array = new int[count];
                fixed(int* ptr = array)

                for (int i = 0; i < count; i++) *ptr = i;
            }
        }
    }
}

The result of the release-built is stunning:

count: 100000000
Function without allocation finished after       871ms
Function with allocation finished after          684ms
Function array finished after                    168ms
Function unsafe array finished after              91ms

The array outperforms even the pre-allocated list by far! I thought that the list was basically an array under the hood -- but how come that the results differ so much?

19
  • 3
    @MANIKANDANNAGALAKSHMI That question answers "which one is faster" but does not issue the "why". This question provides the "which one is faster" as context and asks why. Commented Jan 9, 2017 at 12:55
  • 2
    A List is a wrapper around an array, and of course this wrapper costs time. But it's only a 'big difference' in an artificially small sample. Start doing something real inside that loop and the difference drops quickly. Commented Jan 9, 2017 at 12:56
  • 2
    @MANIKANDANNAGALAKSHMI -- Agree with cubrr. A possible answer here would be a link to an answer under that question (if there is one that not only demonstrates which is faster -- as that question asks -- but goes on to explain why) and then a summary of the substantive info from that answer. Commented Jan 9, 2017 at 12:56
  • 1
    Lists implement a heavier foot print with a ton of extensible methods (Add, Remove, CopyTo, etc), a collection [] does not. Commented Jan 9, 2017 at 12:59
  • 4
    The most direct answer to the 'why' is this one, it's the elimination of boundschecking. Commented Jan 9, 2017 at 13:00

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.