zoukankan      html  css  js  c++  java
  • Dictionary到List转换中的性能问题 转

    在应用泛型中,我们经常使用Dictionary,经常会用到Dictionary到List的转换。

    经过各位高人指点后,做出适当调整,以免误人子弟,特此对关注此帖的同仁深表感谢。希望能继续提醒、斧正。

    Dictionary转换为List通常方法,可以有五种:

    1、创建List的时候,将Dictionary的Value值作为参数

    2、创建List后,调用List.AddRange方法

    3、建立List,循环Dictionary逐个赋值

    4、通过Linq查询,得到结果后调用ToList方法

    5、用Dictionary对象自带的ToList方法

    但是五种方法如何取舍呢?性能方面哪种更好一点呢?

    针对此疑问,特做了测试验证。

    测试结果如下:(经过多次测试,取平均值)

    复制代码
                /*测试结果(时间为毫秒)        
    * * =============================================
    * * 数据 | 10W | 100W | 1000W
    * * ---------------------------------------------
    * * 创建集合 | 2 | 28 | 280
    * * ---------------------------------------------
    * * AddRange | 19 | 33 | 362
    * * ---------------------------------------------
    * * 循环赋值 | 7 | 60 | 869
    * * ---------------------------------------------
    * * Linq查询 | 8 | 7 | 238 此没有相关性,只是作为下面ToList方法的参考
    * * ---------------------------------------------
    * * Linq查询
    * * 后ToList | 11 | 97 | 1627
    * * ---------------------------------------------
    * * ToList方法 | 5 | 23 | 948
    * *
    *
    */
    复制代码

    通过上述结果,可以得出结论:

     结论1:方法1和方法2性能较好,可优先考虑方法1

     结论2:TOList方法性能方面稍差,方法4和方法5不可取。

    具体测试用例代码如下,如有纰漏,请指出:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;

    namespace ToListTest
    {
    class Program
    {
    static void Main(string[] args)
    {
    TestToList();
    }
    ///<summary>
    /// 测试代码
    ///</summary>
    private static void TestToList()
    {
    Dictionary<int, Person> dic = new Dictionary<int, Person>();
    #region 填充数据
    Person p;
    for (int i = 0; i < 100000; i++)
    {
    p = new Person(i, "P_" + i.ToString());
    dic.Add(i, p);
    }
    #endregion

    List<Person> pList;
    Stopwatch watcher = new Stopwatch();

    #region 创建集合对象时,将集合作为参数
    watcher.Reset();
    watcher.Start();

    pList = new List<Person>(dic.Values);
    Console.WriteLine("new List<> {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion

    #region 调用方法AddRange

    pList = new List<Person>();
    watcher.Reset();
    watcher.Start();

    pList.AddRange(dic.Values);

    Console.WriteLine("测试AddRange {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion

    #region 测试循环赋值
    pList = new List<Person>();
    watcher.Reset();
    watcher.Start();

    foreach (var item in dic)
    {
    pList.Add(item.Value);
    }
    Console.WriteLine("测试循环赋值 {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion

    #region 测试Linq

    watcher.Reset();
    watcher.Start();

    //var list = from temp in dic
    // select temp.Value;

    //pList = list as List<Person>; //pList 确实为Null,这样操作错误
    //原因:
    //得到的list为:{System.Linq.Enumerable.WhereSelectEnumerableIterator<KeyValuePair<int,Person>,Person>}

    IEnumerable<Person> list = from temp in dic
    select temp.Value;

    Console.WriteLine("测试Linq {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion

    #region 测试Linq 需要ToList()

    watcher.Reset();
    watcher.Start();
    pList = (from temp in dic
    select temp.Value).ToList();

    Console.WriteLine("测试Linq,需要ToList {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion

    #region 测试ToList
    watcher.Reset();
    watcher.Start();
    pList = dic.Values.ToList<Person>();
    Console.WriteLine("测试ToList {0}", watcher.ElapsedMilliseconds);
    watcher.Stop();



    #endregion


    /*测试结果(时间为毫秒)
    * * =============================================
    * * 数据 | 10W | 100W | 1000W
    * * ---------------------------------------------
    * * 创建集合 | 2 | 28 | 280
    * * ---------------------------------------------
    * * AddRange | 19 | 33 | 362
    * * ---------------------------------------------
    * * 循环赋值 | 7 | 60 | 869
    * * ---------------------------------------------
    * * Linq查询 | 8 | 7 | 238 此没有相关性,只是作为下面ToList方法的参考
    * * ---------------------------------------------
    * * Linq查询
    * * 后ToList | 11 | 97 | 1627
    * * ---------------------------------------------
    * * ToList方法 | 5 | 23 | 948
    * *
    *
    */


    }

    class Person
    {
    private int id;

    public int ID
    {
    get { return id; }
    set { id = value; }
    }

    private string name;

    public string Name
    {
    get { return name; }
    set { name = value; }
    }


    public Person(int id, string name)
    {
    this.id = id;
    this.name = name;
    }

    }
    }



    }
  • 相关阅读:
    [编程语言][java][java se]java泛型中? T K V E含义(学习)
    Effective C++ 第二版 10) 写operator delete
    Cocos2d-x C++调用Android弹出提示框
    面试宝典 问题记录
    送给初入大学的工科男们一篇童话
    二叉树遍历
    webservice的讲解
    在JNI中新开线程遇到问题
    jni调试3(线程调试env变量问题)
    eMMC(KLM8G2FE3B)
  • 原文地址:https://www.cnblogs.com/353373440qq/p/3488367.html
Copyright © 2011-2022 走看看