[技术相关]List、Dictionary转Dictionary的性能分析

1.    背景

  我们经常有对List和Dictionary列表进行复制、转换等操作,在数据量较少时(几万以内)各种转换速度不会被觉察,但是数据量很大时(百万左右),各种转换方式的性能就会体现出来。

  本文档将对列表转换效率进行测试,最终得出效率较高的方法,指导今后软件开发对技术的选择。另外,本文还将对列表转换过程中由另一线程修改列表数据时,是否会出现异常进行确认。

  2013年5月16日星期四

2.    结论

  1、在Dictionary转Dictionary过程中由另一线程修改列表数据时,会出现异常。

  2、采用Dictionary.ToDictionary()的方式速度很慢,100万条需要249毫秒

  3、采用Dictionary.Value.ToList的方式速度很快,100万条数据仅32毫秒;

  4、List.ToDictionary的方式速度需要109毫秒;

3.    环境

  1)开发环境采用VS2008,C#程序,手动编写代码实现。

  2)测试列表中包含100万条数据。

4.    分析

4.1.  过程1:修改列表,是否对转换造成异常

  1、方法:用两个线程,一个线程负责Dictionary转换,一个对列表进行修改。

      结果:系统报错,确实会出现异常。

  2、详细说明(详情参见下方源代码)

     用线程函数TH_DicTest0()进行转换操作,用线程函数TH_DicTest1()进行列表内容修改操作。

4.2.  过程2:列表转换速度分析

  1、方法1:采用Dictionary.ToDictionary()的方式,

    结果:16:44:08 标识:[ToDic时间] 运行时间为:249; 运行次数:1

  2、方法2:采用Dictionary.Value.ToList,然后再List.ToDictionary的方式进行转换;

    结果:

    1)Dictionary.Value.ToList的方式用时:

      16:44:08 标识:[ToList时间] 运行时间为:32; 运行次数:1

    2)List.ToDictionary的方式用时:

      16:44:08 标识:[转Dic时间] 运行时间为:109; 运行次数:1

 

 1         #region Dictionary测试
 2         private MainThread _tt0 = new MainThread();
 3         private MainThread _tt1 = new MainThread();
 4         private Dictionary<int, DataTestItem> _dicTest = new Dictionary<int, DataTestItem>();
 5         private Dictionary<int, DataTestItem> _dicTest1;
 6         private void button17_Click(object sender, EventArgs e)
 7         {
 8             Init_DicTest();
 9 
10             _tt0.Add(TH_DicTest0, 1);
11             _tt1.Add(TH_DicTest1, 1);
12 
13             //_tt1.Start();
14             _tt0.Start();
15         }
16         private void Init_DicTest()
17         {
18             DataTestItem item = null;
19             for (int i = 0; i < 1000000; i++ )
20             {
21                 item = new DataTestItem();
22                 item.a1 = i;
23                 item.a2 = i + 1;
24                 _dicTest.Add(item.a1, item);
25             }
26         }
27         private List<DataTestItem> _lstTest = null;
28         private void TH_DicTest0()
29         {
30             try
31             {
32                 RunTimeScan.Instance().Begin("ToList时间");
33                 _dicTest1 = new Dictionary<int, DataTestItem>();
34                 _lstTest = _dicTest.Values.ToList();
35                 RunTimeScan.Instance().Stop("ToList时间");
36 
37                 RunTimeScan.Instance().Begin("转Dic时间");
38                 foreach (DataTestItem item in _lstTest)
39                 {
40                     _dicTest1.Add(item.a1, item);
41                 }
42                 RunTimeScan.Instance().Stop("转Dic时间");
43 
44                 RunTimeScan.Instance().Begin("ToDic时间");
45                 _dicTest1 = _dicTest.ToDictionary(p => p.Key, p => p.Value);
46                 RunTimeScan.Instance().Stop("ToDic时间");
47 
48                 AddTipMsg(RunTimeScan.Instance().GetRet("ToList时间"));
49                 AddTipMsg(RunTimeScan.Instance().GetRet("转Dic时间"));
50                 AddTipMsg(RunTimeScan.Instance().GetRet("ToDic时间"));
51             }
52             catch (System.Exception ex)
53             {
54                 AddTipMsg(ex.Message + ex.StackTrace);
55             }
56         }
57         private void TH_DicTest1()
58         {
59             try
60             {
61                 RunTimeScan.Instance().Begin("Add_100");
62 
63                 DataTestItem item = null;
64                 for (int i = 0; i < 100; i++)
65                 {
66                     item = new DataTestItem();
67                     item.a1 = _dicTest.Count() + i;
68                     item.a2 = i + 1;
69                     _dicTest.Add(item.a1, item);
70                     Thread.Sleep(20);
71                 }
72 
73                 RunTimeScan.Instance().Stop("Add_100");
74                 AddTipMsg(RunTimeScan.Instance().GetRet("Add_100"));
75             }
76             catch (System.Exception ex)
77             {
78                 AddTipMsg(ex.Message + ex.StackTrace);
79             }
80         }
81         #endregion
View Code

 

转载于:https://www.cnblogs.com/easydw/p/3509238.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值