C# 哪个更好?数组、数组列表或列表<;T>;(在性能和速度方面)
我需要在处理我的网页速度快。要添加的值的计数将是动态的 以上哪一项是首选?有正当理由的支持 编辑:例如:C# 哪个更好?数组、数组列表或列表<;T>;(在性能和速度方面),c#,arrays,performance,list,arraylist,C#,Arrays,Performance,List,Arraylist,我需要在处理我的网页速度快。要添加的值的计数将是动态的 以上哪一项是首选?有正当理由的支持 编辑:例如: string str = "a,b,c"; //Count of the number of elements in str is not fixed string[] arr = str.Split(','); 或者 “不可变”集合的数组, 列表用于可变集合 “不可变”集合-仅在创建时更改,并且许多在以后读取 可变集合-始终有许多更改 性能统计数据(阵列、列表和只读集合): 源代码:
string str = "a,b,c"; //Count of the number of elements in str is not fixed
string[] arr = str.Split(',');
或者
“不可变”集合的数组,
列表
用于可变集合
- “不可变”集合-仅在创建时更改,并且许多在以后读取
- 可变集合-始终有许多更改
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);
}
}
接口方法
{
T生成(int size,Func生成器);
整数和(T项);
T块拷贝(T项);
T类(T项);
}
类数组方法:i方法
{
公共int[]生成(int大小,Func生成器)
{
变量项=新整数[大小];
对于(变量i=0;is.ToList());
}
}
静态类程序
{
静态元组[]检查性能(IMethods方法),其中T:class
{
var stats=新列表();
T source=null;
foreach(新[]中的var信息)
{
新建{Name=“Generate”,Method=newfunc(items=>methods.Generate(10000000,i=>i%2==0?-i:i)),
new{Name=“Sum”,Method=newfunc(items=>{Console.WriteLine(methods.Sum(items));returnitems;}),
新建{Name=“BlockCopy”,Method=newfunc(items=>methods.BlockCopy(items))},
新建{Name=“Sort”,Method=newfunc(items=>methods.BlockCopy(items))},
new{Name=“Sum”,Method=newfunc(items=>{Console.WriteLine(methods.Sum(items));returnitems;}),
}
)
{
整数计数=10;
var stopwatch=新秒表();
秒表。开始();
T res=null;
对于(变量i=0;i列表
总是比arrayList快。列表的
不必将添加到列表中的值装箱
ArrayList
仅“接受”对象,这意味着,当您可以将任何想要添加到列表中的对象添加到列表中时,必须将其装箱(由CLR隐式装箱),然后在需要值时再次(由您显式地)将其解除装箱
编辑:列表
通常应优先于数组列表
- 值类型速度更快,因为它避免了装箱
- 强类型元素
如果希望向调用者公开的列表是不可变的,则List
和ArrayList
都支持这一点:
List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);
List.AsReadOnly()
只读(ArrayList列表);
您的问题是在ArrayList
和List
之间进行选择,但您的示例显示的是一个数组,两者都不是。为什么不自己尝试一下呢?此外,这完全取决于您想对数组、ArrayList或List执行什么操作。我会选择一个最容易使用的数组,并且只在执行操作时担心性能ally需要它。在您特定的情况下尝试每一种,并分析哪一种最适合您的需要。它们都有不同的用途。没有一个通用的“这是最好的”答案适合所有情况。我喜欢[过早优化]的味道早上。List
和ArrayList
使用数组作为备份存储。它们可以
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);
}
}
List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);