c# – 哪个.NET集合更快:枚举foreach Dictionary <>.值或List <>?

c# – 哪个.NET集合更快:枚举foreach Dictionary <>.值或List <>?,第1张

概述这些枚举中的一个比另一个或大约相同吗? (C#中的例子) 情况1: Dictionary<string, object> valuesDict;// valuesDict loaded with thousands of objectsforeach (object value in valuesDict.Values) { /* process */ } 案例2: List<object 这些枚举中的一个比另一个或大约相同吗? (C#中的例子)

情况1:

Dictionary<string,object> valuesDict;// valuesDict loaded with thousands of objectsforeach (object value in valuesDict.Values) { /* process */ }

案例2:

List<object> valuesList;// valuesList loaded with thousands of objectsforeach (object value in valuesList) { /* process */ }

更新:

背景:

字典对于其他地方的键控搜索是有益的(而不是遍历列表),但是如果遍历字典比通过列表慢得多,那么好处将会减少.

更新:
根据许多人的建议,我已经完成了自己的测试.

首先,这些是结果.以下是该计划.

迭代整个集合
Dict:78
凯德:131
清单:76

键控搜索集合
Dict:178
凯德:194
清单:142800

using System;using System.linq;namespace IterateCollections{    public class Data    {        public string ID;        public string Text;    }    public class KeyedData : System.Collections.ObjectModel.KeyedCollection<string,Data>    {        protected overrIDe string GetKeyForItem(Data item)        {            return item.ID;        }    }    class Program    {        static voID Main(string[] args)        {            var dict = new System.Collections.Generic.Dictionary<string,Data>();            var List = new System.Collections.Generic.List<Data>();            var keyd = new KeyedData();            for (int i = 0; i < 10000; i++)            {                string s = i.ToString();                var d = new Data { ID = s,Text = s };                dict.Add(d.ID,d);                List.Add(d);                keyd.Add(d);            }            var sw = new System.Diagnostics.Stopwatch();            sw.Start();            for (int r = 0; r < 1000; r++)            {                foreach (Data d in dict.Values)                {                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            var dictTime = sw.ElapsedMilliseconds;            sw.reset();            sw.Start();            for (int r = 0; r < 1000; r++)            {                foreach (Data d in keyd)                {                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            var keydTime = sw.ElapsedMilliseconds;            sw.reset();            sw.Start();            for (int r = 0; r < 1000; r++)            {                foreach (Data d in List)                {                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            var ListTime = sw.ElapsedMilliseconds;            Console.Writeline("Iterate whole collection");            Console.Writeline("Dict: " + dictTime);            Console.Writeline("Keyd: " + keydTime);            Console.Writeline("List: " + ListTime);            sw.reset();            sw.Start();            for (int r = 0; r < 1000; r++)            {                for (int i = 0; i < 10000; i += 10)                {                    string s = i.ToString();                    Data d = dict[s];                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            dictTime = sw.ElapsedMilliseconds;            sw.reset();            sw.Start();            for (int r = 0; r < 1000; r++)            {                for (int i = 0; i < 10000; i += 10)                {                    string s = i.ToString();                    Data d = keyd[s];                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            keydTime = sw.ElapsedMilliseconds;            sw.reset();            sw.Start();            for (int r = 0; r < 10; r++)            {                for (int i = 0; i < 10000; i += 10)                {                    string s = i.ToString();                    Data d = List.FirstOrDefault(item => item.ID == s);                    if (null == d) throw new ApplicationException();                }            }            sw.Stop();            ListTime = sw.ElapsedMilliseconds * 100;            Console.Writeline("Keyed search collection");            Console.Writeline("Dict: " + dictTime);            Console.Writeline("Keyd: " + keydTime);            Console.Writeline("List: " + ListTime);        }    }

}

更新:

@Blam建议的字典与KeyedCollection的比较.

最快的方法是迭代KeyedCollection项目数组.

但请注意,迭代字典值比KeyedCollection快,而不转换为数组.

请注意,迭代字典值比字典集合快得多.

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

计时来自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);        }    }}
解决方法 使用秒表检查相对容易:

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

List总是获胜,但考虑到两个数据结构的相对复杂性,边距并不像人们预期的那么大.

总结

以上是内存溢出为你收集整理的c# – 哪个.NET集合更快:枚举foreach Dictionary <>.值或List <>?全部内容,希望文章能够帮你解决c# – 哪个.NET集合更快:枚举foreach Dictionary <>.值或List <>?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1225419.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存