web-dev-qa-db-fra.com

Ce qui est mieux? tableau, ArrayList ou List <T> (en termes de performances et de vitesse)

J'ai besoin d'une vitesse rapide dans le traitement de ma page. Le décompte des valeurs à ajouter sera dynamique.

Lequel des énoncés ci-dessus est préféré? Support avec une raison valable.

Modifier: par exemple:

string str = "a,b,c"; //Count of the number of elements in str is not fixed
string[] arr = str.Split(',');

ou,

ArrayList al = new ArrayList();
al.Add(str.Split(','));
19
user1509

List<T> devrait généralement être préféré à ArrayList

  • plus rapide pour les types de valeur car elle évite la boxe.
  • éléments fortement typés

Si vous souhaitez que les listes que vous exposez aux appelants soient immuables, cela est pris en charge par les deux List<T> et ArrayList:

List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);

Votre question porte sur le choix entre ArrayList et List<T>, mais votre exemple montre un tableau, qui n'est ni l'un ni l'autre.

20
Joe

Tableau pour les collections "immuables", List<T> pour les collections mutables.

  • Collection "immuable" - modifiée uniquement lors de la création, et de nombreuses lectures plus tard.
  • Collection Mutable - de nombreux changements en tout temps

Statistiques de performances (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

Code source:

interface IMethods<T>
{
  T Generate(int size, Func<int, int> generator);
   int Sum(T items);
   T BlockCopy(T items);
   T Sort(T items);
}

class ArrayMethods:IMethods<int[]>
{
  public int[] Generate(int size, Func<int, int> 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<List<int>>
{
  public List<int> Generate(int size, Func<int, int> generator)
  {
    var items = new List<int>(size);
    for (var i = 0; i < size; ++i)
      items.Add(generator(i));
    return items;
  }
  public int Sum(List<int> items)
  {
    int sum = 0;
    foreach (var item in items)
      sum += item;
    return sum;
  }
  public List<int> BlockCopy(List<int> items)
  {
    var count = items.Count / 2;
    var res = new List<int>(count);
    var start = items.Count / 4;
    for (var i = 0; i < count; ++i)
      res.Add(items[start + i]);
    return res;
  }
  public List<int> Sort(List<int> items)
  {
    var res = new List<int>(items);
    res.Sort();
    return res;
  }
}
class ReadOnlyCollectionMethods:IMethods<ReadOnlyCollection<int>>
{
  public ReadOnlyCollection<int> Generate(int size, Func<int, int> generator)
  {
    return new ReadOnlyCollection<int>(Enumerable.Range(0, size).Select(generator).ToList());
  }

  public int Sum(ReadOnlyCollection<int> items)
  {
    int sum = 0;
    foreach (var item in items)
      sum += item;
    return sum;
  }


  public ReadOnlyCollection<int> BlockCopy(ReadOnlyCollection<int> items)
  {
    return new ReadOnlyCollection<int>(items.Skip(items.Count / 4).Take(items.Count / 2).ToArray());
  }
  public ReadOnlyCollection<int> Sort(ReadOnlyCollection<int> items)
  {
    return new ReadOnlyCollection<int>(items.OrderBy(s => s).ToList());
  }
}

static class Program
{
  static Tuple<string, TimeSpan>[] CheckPerformance<T>(IMethods<T> methods) where T:class
  {
    var stats = new List<Tuple<string, TimeSpan>>();

    T source = null;
    foreach (var info in new[] 
      { 
        new {Name = "Generate", Method = new Func<T, T>(items => methods.Generate(10000000, i => i % 2 == 0 ? -i : i))}, 
        new {Name = "Sum", Method =  new Func<T, T>(items => {Console.WriteLine(methods.Sum(items));return items;})}, 
        new {Name = "BlockCopy", Method = new Func<T, T>(items => methods.BlockCopy(items))}, 
        new {Name = "Sort", Method = new Func<T, T>(items => methods.BlockCopy(items))}, 
        new {Name = "Sum", Method =  new Func<T, T>(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<string, TimeSpan>(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);
    }
  }
17
Serj-Tm

List <T> va toujours être plus rapide qu'une arrayList. List <T>'s ne doit pas encadrer les valeurs qui leur sont ajoutées.

ArrayList uniquement "accepter" les objets, ce qui signifie que même si vous pouvez ajouter n'importe quel objet de votre choix à la liste, il devra être encadré (implicitement par le CLR) et ensuite il devra être à nouveau déballé (explicitement par vous) lorsque vous avez besoin des valeurs.

edit: voici un joli lien

6
Thousand