[技术相关]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

 


分享给朋友:
您可能感兴趣的文章:
随机阅读: