Which is better? array, ArrayList or List (in terms of performance and speed)

前端 未结 3 1394
南笙
南笙 2020-12-31 00:32

I require a fast speed in processing my page. The count of the values to be added will be dynamic.

Which one of the above is preferred? Support with a valid reason.<

3条回答
  •  鱼传尺愫
    2020-12-31 01:02

    Array for "immutable" collections, List for mutable collections.

    • "Immutable" collection - changed on creation only, and many reading later.
    • Mutable collection - many changes all time

    Performance stats (Array vs List vs ReadonlyCollection):

           Array                List        ReadOnlyCollection         Penalties      Method
    00:00:01.3932446    00:00:01.6677450    00:00:06.2444633    1 vs  1,2  vs  4,5   Generate
    00:00:00.1856069    00:00:01.0291365    00:00:02.0674881    1 vs  5,5  vs 11,1   Sum
    00:00:00.4350745    00:00:00.9422126    00:00:04.5994937    1 vs  2,2  vs 10,6   BlockCopy
    00:00:00.2029309    00:00:00.4272936    00:00:02.2941122    1 vs  2,1  vs 11,3   Sort
    

    Source code:

    interface IMethods
    {
      T Generate(int size, Func generator);
       int Sum(T items);
       T BlockCopy(T items);
       T Sort(T items);
    }
    
    class ArrayMethods:IMethods
    {
      public int[] Generate(int size, Func generator)
      {
        var items = new int[size];
        for (var i = 0; i < items.Length; ++i)
          items[i] = generator(i);
        return items;
      }
      public int Sum(int[] items)
      {
        int sum = 0;
        foreach (var item in items)
          sum += item;
        return sum;
      }
      public int[] BlockCopy(int[] items)
      {
        var res = new int[items.Length / 2];
        Buffer.BlockCopy(items, items.Length / 4 * sizeof(int), res, 0, res.Length * sizeof(int));
        return res;
      }
      public int[] Sort(int[] items)
      {
        var res = new int[items.Length];
        Buffer.BlockCopy(items, 0, res, 0, items.Length * sizeof(int));
        return res;
      }
    }
    class ListMethods : IMethods>
    {
      public List Generate(int size, Func generator)
      {
        var items = new List(size);
        for (var i = 0; i < size; ++i)
          items.Add(generator(i));
        return items;
      }
      public int Sum(List items)
      {
        int sum = 0;
        foreach (var item in items)
          sum += item;
        return sum;
      }
      public List BlockCopy(List items)
      {
        var count = items.Count / 2;
        var res = new List(count);
        var start = items.Count / 4;
        for (var i = 0; i < count; ++i)
          res.Add(items[start + i]);
        return res;
      }
      public List Sort(List items)
      {
        var res = new List(items);
        res.Sort();
        return res;
      }
    }
    class ReadOnlyCollectionMethods:IMethods>
    {
      public ReadOnlyCollection Generate(int size, Func generator)
      {
        return new ReadOnlyCollection(Enumerable.Range(0, size).Select(generator).ToList());
      }
    
      public int Sum(ReadOnlyCollection items)
      {
        int sum = 0;
        foreach (var item in items)
          sum += item;
        return sum;
      }
    
    
      public ReadOnlyCollection BlockCopy(ReadOnlyCollection items)
      {
        return new ReadOnlyCollection(items.Skip(items.Count / 4).Take(items.Count / 2).ToArray());
      }
      public ReadOnlyCollection Sort(ReadOnlyCollection items)
      {
        return new ReadOnlyCollection(items.OrderBy(s => s).ToList());
      }
    }
    
    static class Program
    {
      static Tuple[] CheckPerformance(IMethods methods) where T:class
      {
        var stats = new List>();
    
        T source = null;
        foreach (var info in new[] 
          { 
            new {Name = "Generate", Method = new Func(items => methods.Generate(10000000, i => i % 2 == 0 ? -i : i))}, 
            new {Name = "Sum", Method =  new Func(items => {Console.WriteLine(methods.Sum(items));return items;})}, 
            new {Name = "BlockCopy", Method = new Func(items => methods.BlockCopy(items))}, 
            new {Name = "Sort", Method = new Func(items => methods.BlockCopy(items))}, 
            new {Name = "Sum", Method =  new Func(items => {Console.WriteLine(methods.Sum(items));return items;})}, 
          }
         )
        {
          int count = 10;
          var stopwatch = new Stopwatch();
          stopwatch.Start();
          T res = null;
          for (var i = 0; i < count; ++i)
            res = info.Method(source);
          stopwatch.Stop();
          source = res;
          stats.Add(new Tuple(info.Name, stopwatch.Elapsed));
        }
        return stats.ToArray();
      }
    
      static void Main()
      {
        var arrayStats = CheckPerformance(new ArrayMethods());
        var listStats = CheckPerformance(new ListMethods());
        var rcStats = CheckPerformance(new ReadOnlyCollectionMethods());
    
        Console.WriteLine("       Array                List        ReadOnlyCollection         Penalties      Method");
        for(var i = 0; i < arrayStats.Length; ++i)
        {
          Console.WriteLine("{0}    {1}    {2}    1 vs {3,4:f1}  vs {4,4:f1}   {5}", arrayStats[i].Item2, listStats[i].Item2, rcStats[i].Item2, 
            listStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds,
            rcStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds, arrayStats[i].Item1);
        }
      }
    

提交回复
热议问题