Dictionary vs List 效率


話說Dictionary的效率比List的高?

為什么高呢?這個大家可以百度下。

當然,我也並不是完全認同。然后后了測試,反正結果是……

其實在很多情況下是根據不同的使用環境來選擇使用。

例如:List<int> 和 Dictionary<int,int>

就拿這兩個的添加和數據遍歷或者是查找單一數據體

當循環遍歷查找1500次,發現list的速度降低了很多。

可以發現for循環查找的效率隨次數增加而遞減。那么我也很好奇,為什么會這樣子捏?List一次的Find和1000次的Find會有這么大的效率之差?初步猜測是由於List的for循環引起。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ListVsDictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch watch1 = new Stopwatch();
            Stopwatch watch2 = new Stopwatch();
            Dictionary<int, Baga> dic = new Dictionary<int, Baga>();
            List<Baga> list = new List<Baga>();
            Console.WriteLine("Add Function:");
            watch1.Start();
            for (int i = 0; i < 9000; i++)
            {
                dic.Add(i, new Baga(i, i, 8));
            }
            Console.WriteLine("Dic: \t" + watch1.Elapsed);
            watch1.Stop();
            watch2.Start();
            for (int i = 0; i < 9000; i++)
            {
                list.Add(new Baga(i, i, 8));
            }
            Console.WriteLine("List: \t" + watch2.Elapsed);
            watch2.Stop();

            Console.WriteLine("For Function:");
            watch1.Start();
            foreach (var item in dic)
            {
                var dd = item.Value.ToString();
            }
            Console.WriteLine("Dic: \t" + watch1.Elapsed);
            watch1.Stop();
            watch2.Start();
            foreach (var item in list)
            {
                var dd = item;
            }
            Console.WriteLine("List: \t" + watch2.Elapsed);
            watch2.Stop();


            Console.WriteLine("Search Function:");
            watch1.Start();
            Baga idVal1 = new Baga();
            dic.TryGetValue(99, out idVal1);
            Console.WriteLine("Dic: \t" + watch1.Elapsed);
            watch1.Stop();

            watch2.Start();
            list.Find(x => x.Id == 99);
            Console.WriteLine("List: \t" + watch2.Elapsed);
            watch2.Stop();

            Console.WriteLine("For Search Function:");
            watch1.Start();
            Baga idVal = new Baga();
            for (int i = 0; i < 1500; i++)
            {
                var getDic = dic.TryGetValue(999, out idVal);
            }
            Console.WriteLine("Dic: \t" + watch1.Elapsed);
            watch1.Stop();

            watch2.Start();
            for (int i = 0; i < 1500; i++)
            {
                var getList = list.Find(x => x.Id == 999);
            }
            Console.WriteLine("List: \t" + watch2.Elapsed);
            watch2.Stop();


        }


    }
    public class Baga
    {
        public Baga() { }
        #region 初始化
        public Baga(int id, int num, int type)
        {
            this.Id = id;
            this.Num = num;
            this.Type = type;
            this.Name = "asdfffffffffffffffffffffffffffffasdfffffffffffffffffff";
        }
        #endregion

        public int Id { get; set; }
        public int Num { get; set; }
        public int Type { get; set; }

        public string Name { get; set; }
        public int FriendsToken { get; private set; }
        public int Energy { get; private set; }
        public int MaxEnergy { get; private set; }
    }
}

 

最后,給出MSDN上的建議:

         1.如果需要非常快地添加、刪除和查找項目,而且不關心集合中項目的順序,那么首先應該考慮使用 System.Collections.Generic.Dictionary<TKey, TValue>(或者您正在使用 .NET Framework 1.x,可以考慮 Hashtable)。三個基本操作(添加、刪除和包含)都可快速操作,即使集合包含上百萬的項目。

         2.如果您的使用模式很少需要刪除和大量添加,而重要的是保持集合的順序,那么您仍然可以選擇 List<T>。雖然查找速度可能比較慢(因為在搜索目標項目時需要遍歷基礎數組),但可以保證集合會保持特定的順序。

         3.您可以選擇 Queue<T> 實現先進先出 (FIFO) 順序或 Stack<T> 實現后進先出 (LIFO) 順序。雖然 Queue<T> 和 Stack<T> 都支持枚舉集合中的所有項目,但前者只支持在末尾插入和從開頭刪除,而后者只支持從開頭插入和刪除。

         4.如果需要在實現快速插入的同時保持順序,那么使用新的 LinkedList<T> 集合可幫助您提高性能。與 List<T> 不同,LinkedList<T> 是作為動態分配的對象鏈實現。與 List<T> 相比,在集合中間插入對象只需要更新兩個連接和添加新項目。從性能的角度來看,鏈接列表的缺點是垃圾收集器會增加其活動,因為它必須遍歷整個列表以確保沒有對象沒有被釋放。另外,由於每個節點相關的開銷以及每個節點在內存中的位置等原因,大的鏈接列表可能會出現性能問題。雖然將項目插入到 LinkedList<T> 的實際操作比在 List<T> 中插入要快得多,但是找到要插入新值的特定位置仍需遍歷列表並找到正確的位置。

我們還可以參考下:http://www.cnblogs.com/qinersky902/p/4999970.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM