哪个更好?数组、ArrayList 或 List<T>(在性能和速度方面)
Posted
技术标签:
【中文标题】哪个更好?数组、ArrayList 或 List<T>(在性能和速度方面)【英文标题】:Which is better? array, ArrayList or List<T> (in terms of performance and speed) 【发布时间】:2012-06-04 15:29:49 【问题描述】:我需要快速处理我的页面。要添加的值的计数将是动态的。
以上哪一项是首选?有正当理由的支持。
编辑:例如:
string str = "a,b,c"; //Count of the number of elements in str is not fixed
string[] arr = str.Split(',');
或者,
ArrayList al = new ArrayList();
al.Add(str.Split(','));
【问题讨论】:
为什么不自己试试呢?此外,这完全取决于您想对 Array、ArrayList 或 ListList<T>
和 ArrayList
使用数组作为后备存储。它们可以和数组一样快(而且确实如此),但它们不能更快。
类似于***.com/questions/128636/…
【参考方案1】:
List<T>
通常应优先于 ArrayList
如果您希望向调用者公开的列表是不可变的,List<T>
和 ArrayList
都支持:
List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);
您的问题是关于在 ArrayList
和 List<T>
之间进行选择,但您的示例显示了一个数组,但两者都不是。
【讨论】:
那么什么时候选择 ArrayList 比 List 更好?【参考方案2】:“不可变”集合的数组,
List<T>
用于可变集合。
性能统计数据(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
源代码:
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);
【讨论】:
除了数组不是真正不可变的,IEnumerable<T>
或 IReadOnlyList<T>
(.Net 4.5 中的新功能)是。
数组不是不可变的。而是使用ReadOnlyCollection<T>
作为List<T>
周围的不可变包装器 - 通常通过调用List<T>.AsReadOnly()
。
数组是可变的,当需要不变性时应该避免:blogs.msdn.com/b/ericlippert/archive/2008/09/22/…
@DarkGray,事实上,Array 不是不可变的,即创建后可以修改(例如myArray[i] = newValue
)。至于性能,您的统计数据毫无意义,因为它们没有显示他们是如何进行测量的。固定大小(即不能添加/删除元素)与不可变(这意味着现有元素也不能替换)不同。
其中一些测试存在缺陷。例如,您的 Array 的 Generate 函数使用了预先知道其大小的事实。但是您不会在 List 生成中做类似的事情(例如,在 List<T>
构造函数中使用容量参数)。【参考方案3】:
List <T>
总是比 arrayList 快。 List <T>'s
不必将添加到其中的值装箱。
ArrayList
仅“接受”对象,这意味着虽然您可以将任何您想要的对象添加到列表中,但必须将其装箱(由 CLR 隐式)然后必须再次取消装箱(显式由您)当您需要这些值时。
编辑:here is a nice link
【讨论】:
装箱差异仅适用于值类型。对于引用类型,两者相等。以上是关于哪个更好?数组、ArrayList 或 List<T>(在性能和速度方面)的主要内容,如果未能解决你的问题,请参考以下文章
哪个更适合使用,vector 或 arraylist? [复制]
哪个更适合使用,vector 或 arraylist? [复制]