C# 哪个.NET集合更快:枚举foreach字典<>;。值或列表<>;?
这些枚举中的一个比另一个快还是差不多?(C#中的示例) 案例1:C# 哪个.NET集合更快:枚举foreach字典<>;。值或列表<>;?,c#,.net,performance,enumeration,C#,.net,Performance,Enumeration,这些枚举中的一个比另一个快还是差不多?(C#中的示例) 案例1: Dictionary<string, object> valuesDict; // valuesDict loaded with thousands of objects foreach (object value in valuesDict.Values) { /* process */ } 计时来自Windows控制台应用程序(发布版本)。以下是源代码: using System; using System.
Dictionary<string, object> valuesDict;
// valuesDict loaded with thousands of objects
foreach (object value in valuesDict.Values) { /* process */ }
计时来自Windows控制台应用程序(发布版本)。以下是源代码:
using System;
using System.Collections.Generic;
using System.Linq;
namespace IterateCollections
{
public class GUIDkeyCollection : System.Collections.ObjectModel.KeyedCollection<Guid, GUIDkey>
{
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
public GUIDkeyCollection() : base() { }
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected override Guid GetKeyForItem(GUIDkey item)
{
// In this example, the key is the part number.
return item.Key;
}
public GUIDkey[] ToArray()
{
return Items.ToArray();
}
//[Obsolete("Iterate using .ToArray()", true)]
//public new IEnumerator GetEnumerator()
//{
// throw new NotImplementedException("Iterate using .ToArray()");
//}
}
public class GUIDkey : Object
{
private Guid key;
public Guid Key
{
get
{
return key;
}
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || !(obj is GUIDkey)) return false;
GUIDkey item = (GUIDkey)obj;
return (Key == item.Key);
}
public override int GetHashCode() { return Key.GetHashCode(); }
public GUIDkey(Guid guid)
{
key = guid;
}
}
class Program
{
static void Main(string[] args)
{
const int itemCount = 10000;
const int repetitions = 1000;
const string resultFormat = "{0,18}: {1,5:D} ms";
Console.WriteLine("Iterate {0:N0} times over collection of {1:N0} items", repetitions, itemCount);
var dict = new Dictionary<Guid, GUIDkey>();
var keyd = new GUIDkeyCollection();
for (int i = 0; i < itemCount; i++)
{
var d = new GUIDkey(Guid.NewGuid());
dict.Add(d.Key, d);
keyd.Add(d);
}
var sw = new System.Diagnostics.Stopwatch();
long time;
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (KeyValuePair<Guid, GUIDkey> w in dict)
{
if (null == w.Value) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dictionary Pair", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in dict.Values)
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dictionary Values", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in dict.Values.ToArray())
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dict Val ToArray", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in keyd)
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "KeyedCollection", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in keyd.ToArray())
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "KeyedC. ToArray", time);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间迭代集合
{
公共类GUIDkeyCollection:System.Collections.ObjectModel.KeyedCollection
{
//此无参数构造函数调用基类构造函数
//它指定字典阈值为0,以便内部
//将项添加到词典中后,即创建词典
//收藏。
//
公共GUIDkeyCollection():base(){}
//这是唯一绝对必须重写的方法,
//因为没有它,KeyedCollection无法提取
//项目中的关键点。
//
受保护的覆盖Guid GetKeyForItem(GUIDkey项)
{
//在本例中,键是零件号。
返回项。键;
}
公共GUIDkey[]ToArray()
{
返回项目。ToArray();
}
//[过时(“使用.ToArray()进行迭代”,true)]
//公共新IEnumerator GetEnumerator()
//{
//抛出新的NotImplementedException(“使用.ToArray()迭代”);
//}
}
公共类GUIDkey:Object
{
私钥;
公钥
{
得到
{
返回键;
}
}
公共覆盖布尔等于(对象对象对象)
{
//检查null并比较运行时类型。
如果(obj==null | |!(obj是GUIDkey))返回false;
GUIDkey项目=(GUIDkey)obj;
返回(Key==item.Key);
}
公共重写int GetHashCode(){return Key.GetHashCode();}
公共Guid(Guid)
{
key=guid;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
常量int itemCount=10000;
常数int重复次数=1000;
常量字符串resultFormat=“{0,18}:{1,5:D}ms”;
WriteLine(“在{1:N0}项集合上迭代{0:N0}次”,重复,itemCount);
var dict=新字典();
var keyd=new GUIDkeyCollection();
对于(int i=0;i
差不多是同一时间。当然,一旦您的流程包含任何代码,它就不会被注意到
但是你为什么要听互联网上随机出现的人讲话呢?试试看
该类可能很有用。如果要按键查找,请按字典。
按键查找字典非常快,因为这就是它的设计目的 foreach的差异将很小
如果密钥也是一个属性,则考虑KEYEDGE集合
.NET有许多集合。
如果你的对象有一个可以被表示为一个It32的自然键,那么考虑重写GethAsHeCuffE()。
如果您的对象具有GUID的自然键,则考虑KEYDED集合和重写GethHAc码,并等于
和对非关键属性的访问考虑LINQ而不是FACH中断;p>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Diagnostics;
namespace IntIntKeyedCollection
{
class Program
{
static void Main(string[] args)
{
Guid findGUID = Guid.NewGuid();
GUIDkeyCollection gUIDkeyCollection = new GUIDkeyCollection();
gUIDkeyCollection.Add(new GUIDkey(findGUID));
gUIDkeyCollection.Add(new GUIDkey(Guid.NewGuid()));
gUIDkeyCollection.Add(new GUIDkey(Guid.NewGuid()));
GUIDkey findGUIDkey = gUIDkeyCollection[findGUID]; // lookup by key (behaves like a dict)
Console.WriteLine(findGUIDkey.Key);
Console.WriteLine(findGUIDkey.GetHashCode());
Console.WriteLine(findGUID);
Console.WriteLine(findGUID.GetHashCode());
Console.ReadLine();
}
public class GUIDkeyCollection : KeyedCollection<Guid, GUIDkey>
{
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
public GUIDkeyCollection() : base() { }
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected override Guid GetKeyForItem(GUIDkey item)
{
// In this example, the key is the part number.
return item.Key;
}
}
public class GUIDkey : Object
{
private Guid key;
public Guid Key
{
get
{
return key;
}
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || !(obj is GUIDkey)) return false;
GUIDkey item = (GUIDkey)obj;
return (Key == item.Key);
}
public override int GetHashCode() { return Key.GetHashCode(); }
public GUIDkey(Guid guid)
{
key = guid;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Collecti
Iterate 1,000 times over collection of 10,000 items
Dictionary Pair: 519 ms
Dictionary Values: 95 ms
Dict Val ToArray: 92 ms
KeyedCollection: 141 ms
KeyedC. ToArray: 17 ms
using System;
using System.Collections.Generic;
using System.Linq;
namespace IterateCollections
{
public class GUIDkeyCollection : System.Collections.ObjectModel.KeyedCollection<Guid, GUIDkey>
{
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
public GUIDkeyCollection() : base() { }
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected override Guid GetKeyForItem(GUIDkey item)
{
// In this example, the key is the part number.
return item.Key;
}
public GUIDkey[] ToArray()
{
return Items.ToArray();
}
//[Obsolete("Iterate using .ToArray()", true)]
//public new IEnumerator GetEnumerator()
//{
// throw new NotImplementedException("Iterate using .ToArray()");
//}
}
public class GUIDkey : Object
{
private Guid key;
public Guid Key
{
get
{
return key;
}
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || !(obj is GUIDkey)) return false;
GUIDkey item = (GUIDkey)obj;
return (Key == item.Key);
}
public override int GetHashCode() { return Key.GetHashCode(); }
public GUIDkey(Guid guid)
{
key = guid;
}
}
class Program
{
static void Main(string[] args)
{
const int itemCount = 10000;
const int repetitions = 1000;
const string resultFormat = "{0,18}: {1,5:D} ms";
Console.WriteLine("Iterate {0:N0} times over collection of {1:N0} items", repetitions, itemCount);
var dict = new Dictionary<Guid, GUIDkey>();
var keyd = new GUIDkeyCollection();
for (int i = 0; i < itemCount; i++)
{
var d = new GUIDkey(Guid.NewGuid());
dict.Add(d.Key, d);
keyd.Add(d);
}
var sw = new System.Diagnostics.Stopwatch();
long time;
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (KeyValuePair<Guid, GUIDkey> w in dict)
{
if (null == w.Value) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dictionary Pair", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in dict.Values)
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dictionary Values", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in dict.Values.ToArray())
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "Dict Val ToArray", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in keyd)
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "KeyedCollection", time);
sw.Reset();
sw.Start();
for (int r = 0; r < repetitions; r++)
{
foreach (GUIDkey d in keyd.ToArray())
{
if (null == d) throw new ApplicationException();
}
}
sw.Stop();
time = sw.ElapsedMilliseconds;
Console.WriteLine(resultFormat, "KeyedC. ToArray", time);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Diagnostics;
namespace IntIntKeyedCollection
{
class Program
{
static void Main(string[] args)
{
Guid findGUID = Guid.NewGuid();
GUIDkeyCollection gUIDkeyCollection = new GUIDkeyCollection();
gUIDkeyCollection.Add(new GUIDkey(findGUID));
gUIDkeyCollection.Add(new GUIDkey(Guid.NewGuid()));
gUIDkeyCollection.Add(new GUIDkey(Guid.NewGuid()));
GUIDkey findGUIDkey = gUIDkeyCollection[findGUID]; // lookup by key (behaves like a dict)
Console.WriteLine(findGUIDkey.Key);
Console.WriteLine(findGUIDkey.GetHashCode());
Console.WriteLine(findGUID);
Console.WriteLine(findGUID.GetHashCode());
Console.ReadLine();
}
public class GUIDkeyCollection : KeyedCollection<Guid, GUIDkey>
{
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
public GUIDkeyCollection() : base() { }
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected override Guid GetKeyForItem(GUIDkey item)
{
// In this example, the key is the part number.
return item.Key;
}
}
public class GUIDkey : Object
{
private Guid key;
public Guid Key
{
get
{
return key;
}
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || !(obj is GUIDkey)) return false;
GUIDkey item = (GUIDkey)obj;
return (Key == item.Key);
}
public override int GetHashCode() { return Key.GetHashCode(); }
public GUIDkey(Guid guid)
{
key = guid;
}
}
}
}
var d = new Dictionary<string, object>();
var s = new List<object>();
for (int i =0 ; i != 10000000 ; i++) {
d.Add(""+i, i);
s.Add(i);
}
var sw = new Stopwatch();
sw.Start();
foreach(object o in d.Values) {
if (o == null) throw new ApplicationException();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
foreach (object o in s) {
if (o == null) throw new ApplicationException();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Dict List
---- ----
136 107
139 108
136 108
class speedtest
{
static void Main(string[] args)
{
int size = 10000000;
Dictionary<string, object> valuesDict = new Dictionary<string, object>();
List<object> valuesList = new List<object>();
for (int i = 0; i < size; i++)
{
valuesDict.Add(i.ToString(), i);
valuesList.Add(i);
}
// valuesDict loaded with thousands of objects
Stopwatch s = new Stopwatch();
s.Start();
foreach (object value in valuesDict.Values) { /* process */ }
s.Stop();
Stopwatch s2 = new Stopwatch();
s2.Start();
foreach (object value in valuesList) { /* process */ }
s.Stop();
Console.WriteLine("Size {0}, Dictonary {1}ms, List {2}ms",size,s.ElapsedMilliseconds,s2.ElapsedMilliseconds);
Console.ReadLine();
}
}
Outputs:
Size 10000000, Dictonary 73ms, List 63ms
void Main()
{
int i = 0;
var dict = new Dictionary<string, object>();
var list = new List<object>();
for (i = 0; i < 30000; i++)
{
var foo = new Foo();
dict.Add(i.ToString(), foo);
list.Add(foo);
}
var dictWatch = new Stopwatch();
dictWatch.Start();
for (i = 0; i < 10000; i++)
{
foreach (var foo in dict.Values) {}
}
dictWatch.Stop();
Console.WriteLine("Dictionary: " + dictWatch.ElapsedMilliseconds);
var listWatch = new Stopwatch();
listWatch.Start();
for (i = 0; i < 10000; i++)
{
foreach (var foo in list) {}
}
listWatch.Stop();
Console.WriteLine("List: " + listWatch.ElapsedMilliseconds);
}
class Foo {}