本文来自:http://www.cnblogs.com/353373440qq/p/3488367.html

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

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

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

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

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

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

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

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

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

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

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

  1. /*测试结果(时间为毫秒)
    * * =============================================
    * * 数据 | 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不可取。

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

  1. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
  2.  
  3. 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
  4.  
  5. List<Person> pList;
    Stopwatch watcher = new Stopwatch();
  6.  
  7. #region 创建集合对象时,将集合作为参数
    watcher.Reset();
    watcher.Start();
  8.  
  9. pList = new List<Person>(dic.Values);
    Console.WriteLine("new List<>\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion
  10.  
  11. #region 调用方法AddRange
  12.  
  13. pList = new List<Person>();
    watcher.Reset();
    watcher.Start();
  14.  
  15. pList.AddRange(dic.Values);
  16.  
  17. Console.WriteLine("测试AddRange\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion
  18.  
  19. #region 测试循环赋值
    pList = new List<Person>();
    watcher.Reset();
    watcher.Start();
  20.  
  21. foreach (var item in dic)
    {
    pList.Add(item.Value);
    }
    Console.WriteLine("测试循环赋值\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion
  22.  
  23. #region 测试Linq
  24.  
  25. watcher.Reset();
    watcher.Start();
  26.  
  27. //var list = from temp in dic
    // select temp.Value;
  28.  
  29. //pList = list as List<Person>; //pList 确实为Null,这样操作错误
    //原因:
    //得到的list为:{System.Linq.Enumerable.WhereSelectEnumerableIterator<KeyValuePair<int,Person>,Person>}
  30.  
  31. IEnumerable<Person> list = from temp in dic
    select temp.Value;
  32.  
  33. Console.WriteLine("测试Linq\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion
  34.  
  35. #region 测试Linq 需要ToList()
  36.  
  37. watcher.Reset();
    watcher.Start();
    pList = (from temp in dic
    select temp.Value).ToList();
  38.  
  39. Console.WriteLine("测试Linq,需要ToList\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
    #endregion
  40.  
  41. #region 测试ToList
    watcher.Reset();
    watcher.Start();
    pList = dic.Values.ToList<Person>();
    Console.WriteLine("测试ToList\t{0}", watcher.ElapsedMilliseconds);
    watcher.Stop();
  42.  
  43. #endregion
  44.  
  45. /*测试结果(时间为毫秒)
    * * =============================================
    * * 数据 | 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
    * *
    * */
  46.  
  47. }
  48.  
  49. class Person
    {
    private int id;
  50.  
  51. public int ID
    {
    get { return id; }
    set { id = value; }
    }
  52.  
  53. private string name;
  54.  
  55. public string Name
    {
    get { return name; }
    set { name = value; }
    }
  56.  
  57. public Person(int id, string name)
    {
    this.id = id;
    this.name = name;
    }
  58.  
  59. }
    }
  60.  
  61. }

Dictionary到List转换中的性能问题 转的更多相关文章

  1. List<T>与Dictionary<string,T>频繁检索的性能差距

    一直对LINQ简洁高效的语法青睐有加,对于经常和资料库,SQL语法打交道的C#开发者来说,LINQ无疑是一个非常不错的选择,当要在List<T>(T为一个普通对象)集合中查找满足某些条件的 ...

  2. 【翻译】.NET 5中的性能改进

    [翻译].NET 5中的性能改进 在.NET Core之前的版本中,其实已经在博客中介绍了在该版本中发现的重大性能改进. 从.NET Core 2.0到.NET Core 2.1到.NET Core ...

  3. 如何借助 OVN 来提高 OVS 在云计算环境中的性能

    众所周知,OpenvSwitch 以其丰富的功能和不错的性能,已经成为 Openstack 部署中最受欢迎的虚拟交换机.由于 Openstack Neutron 的架构引入了一些性能问题,比如 neu ...

  4. 【SQL系列】深入浅出数据仓库中SQL性能优化之Hive篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SQL系列]深入浅出数据仓库中SQL性能优化之 ...

  5. 【译】ASP.NET Core 6 中的性能改进

    原文 | Brennan Conroy 翻译 | 郑子铭 受到 Stephen Toub 关于 .NET 性能的博文的启发,我们正在写一篇类似的文章来强调 6.0 中对 ASP.NET Core 所做 ...

  6. 优化Web中的性能

    优化Web中的性能 简介 web的优化就是一场阻止http请求最终访问到数据库的战争. 优化的方式就是加缓存,在各个节点加缓存. web请求的流程及节点 熟悉流程及节点,才能定位性能的问题.而且优化的 ...

  7. Ionic中使用Chart.js进行图表展示以及在iOS/Android中的性能差异

    Angular Chart 简介 在之前的文章中介绍了使用 Ionic 开发跨平台(iOS & Android)应用中遇到的一些问题的解决方案. 在更新0.1.3版本的过程中遇到了需要使用图表 ...

  8. 使用kettle转换中的JavaScript对密码进行加密和解密

    日常开发中,为了确保账号和密码的安全,时常要对密码进行加密和解密.然而kettle是怎么对密码进行加密和解密的呢? 下面的代码需要再转换中的JavaScript中运行. var encrypted_p ...

  9. 使用List,Dictionary加载数据库中的数据

    情景描述:数据库中有一张设备表,字段DWDM存放的是各个厂编号,字段ZNBH存放的是设备编号.其中DWDM跟ZNBH是一对多的关系.需要将数据库中的值加载到List<Dictionary< ...

随机推荐

  1. Reverse Linked List 解答

    Question Reverse a singly linked list. Solution 1 -- Iterative Remember to set head.next = null or i ...

  2. python-MySQL库简单安装

    1  raise EnvironmentError("%s not found" % (mysql_config.path,)) EnvironmentError: mysql_c ...

  3. Android学习总结——Content Provider

    原文地址:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Content Provider内容提供者 : and ...

  4. [Exception] 当前 TransactionScope 已完成

    本文来自:http://www.cnblogs.com/loafer/archive/2010/06/03/TransactionScopeComplete.html 捕获异常的时候 经常会碰到这个异 ...

  5. iOS安全攻防(二十三):Objective-C代码混淆

    iOS安全攻防(二十三):Objective-C代码混淆 class-dump能够非常方便的导出程序头文件,不仅让攻击者了解了程序结构方便逆向,还让着急赶进度时写出的欠完好的程序给同行留下笑柄. 所以 ...

  6. 【剑指offer】Q40:数组中出现一次的数

    书里面关于分类的推断有些麻烦,通过某一位为0为1来对数组元素进行分类.假如第3位为1.那么也就是元素x & 8 等于或不等于0,所以不是必需非的用第几位去推断. def once(array) ...

  7. Web安全技术(3)-浏览器的跨域访问

    http://www.blogjava.net/linli/archive/2015/04/22/424584.html 一.浏览器介绍 对于Web应用来说,浏览器是最重要的客户端. 目前浏览器五花八 ...

  8. Ubuntu 12.04 搭建 Eclipse Android 开发环境(转)

    Ubuntu 12.04 搭建 Eclipse Android 开发环境 http://blog.sina.com.cn/s/blog_93dc666c0101b39p.html (2012-09-0 ...

  9. java中List的用法

    list的添加删除等操作 import java.util.*; class TestList { public static void main(String[] args) { List<S ...

  10. C#自定义控件在添加引用后不显示在工具箱的解决方法

    先说一些背景: 在开发C#项目时,发现很多控件存在复用的情况,控件的属性都是要设置成一样的,我就想,能不能设置一个类来存放这个控件,这样我每次用的时候直接加一些特殊的操作就可以了,不需要再次设置控件属 ...