C# 哪个更好?数组、ArrayList 或 List<T>(在性能和速度方面)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10815565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:22:37  来源:igfitidea点击:

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

c#arraysperformancelistarraylist

提问by user1509

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.

以上哪一项是首选?有正当理由支持。

Edit: For eg:

编辑:例如:

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

or,

或者,

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

采纳答案by Joe

List<T>should generally be preferred over ArrayList

List<T>通常应该优先于 ArrayList

  • faster for value types as it avoids boxing.
  • strongly typed elements
  • 值类型更快,因为它避免了装箱。
  • 强类型元素

If you want lists you expose to callers to be immutable, this is supported by both List<T>and ArrayList:

如果您希望向调用者公开的列表是不可变的,则List<T>和都支持ArrayList

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

Your question asks about choosing between ArrayListand List<T>, but your example shows an array, which is neither.

您的问题是在ArrayList和之间进行选择List<T>,但您的示例显示了一个数组,但两者都不是。

回答by Serj-Tm

Array for "immutable" collections, List<T>for mutable collections.

用于“不可变”集合的数组, List<T>用于可变集合。

  • "Immutable" collection - changed on creation only, and many reading later.
  • Mutable collection - many changes all time
  • “不可变”集合 - 仅在创建时更改,稍后阅读。
  • 可变集合 - 一直有很多变化

Performance stats (Array vs List vs ReadonlyCollection):

性能统计(数组 vs 列表 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>
{
  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);
    }
  }

回答by Thousand

List <T>is always gonna be faster than an arrayList. List <T>'sdont have to box the values that are added to them.

List <T>总是会比 arrayList 快。List <T>'s不必将添加到它们的值装箱。

ArrayListonly "accept" objects, so that means that while you can add any object you want to the list, it will have to be boxed (implicitly by the CLR) and then it has to be unboxed again (explicitly by you) when you need the values.

ArrayList只“接受”对象,这意味着虽然您可以将任何您想要的对象添加到列表中,但它必须被装箱(由 CLR 隐式),然后在您需要时必须再次拆箱(由您明确地)价值。

edit: here is a nice link

编辑:这是一个很好的链接